如何在 AWS 上安全地生成密钥?

信息安全 密钥管理 openssl 密钥生成
2021-09-07 05:03:56

我们的应用程序需要使用 openssl 为 AWS 上的长期存储生成安全密钥。但我见过一些例子,AWS 机器上的熵降到了危险的低水平,这似乎不是 100% 安全的。人们在某些情况下报告了低熵。

确保您在 AWS 上生成强密钥的最简单方法是什么?

例如,有没有办法:

  • 阻止执行,直到有足够的熵作为故障安全
  • 具有更多/更高质量熵的种子机
  • 用其他一些硬件补充 AWS 以提供良好的随机性来源

我看过random.org,但是对于生产环境来说,使用外部Web 服务似乎不够合适或不够快。

4个回答

这个“低熵”的口头禅是个废话。有关详细信息,请参阅此答案执行摘要是:特别是某些软件/dev/random可能会报告“低熵”并由于没有实际意义的原因而阻塞。熵被“耗尽”的想法来自一个数学模型,该模型与现实只有微弱的联系,并且只有在将随机性用于“理论上的信息安全”算法时才可能(理论上)提供任何安全增益。RSA 或 AES 等常用算法不属于此类。

所以你需要做的是以下几点:

  • OpenSSL 应该正常使用/dev/urandom,避免这个问题。如果问题发生,它将表现为“阻塞”行为(密钥生成花费了异常的时间,没有使用 CPU)。
  • /dev/random如果出现问题,用新鲜的伪随机“补充” ,这就足够了就像是:dd if=/dev/urandom of=/dev/random bs=1024 count=64

然而,还有一个问题并不那么容易处理。云系统是虚拟机,可以与同一硬件上的其他虚拟机同时运行。当两个执行线程在同一个 CPU 的两个内核上运行时,即使它们与不同的虚拟机相关,它们也会共享一级缓存,并且可能会相互监视。该技术涉及在使用与目标代码相同的缓存行的数组中进行内存访问,并通过注意何时从缓存中驱逐某些数组元素来重建目标机密。

工作原型已在实验室条件下进行了演示。它们是否可以应用于实际设置取决于很多参数,目前尚不清楚。不过,这是有道理的。结论是,如果你认真对待密钥,那么你应该努力在自己的硬件上运行,或者至少从云提供商那里获得一些保证,即你的虚拟机不会与其他客户的虚拟机共享相同的硬件服务器.

旧线程,但好问题,这里的几个答案并不总是特定于 AWS 机器甚至云虚拟机,正如问题中提到的那样,所以我建议看看Lemur团队的推荐,它适用于更广泛的场景:“您希望花费多少精力确保 Lemur 具有良好的熵可供使用取决于您的特定风险承受能力以及 Lemur 的配置方式。如果您希望为您的系统生成更多熵,我们建议您采取查看以下资源:”然后他们继续推荐haveged

对于那些有兴趣阅读有关低熵问题的更多信息的人,以下论文An Analysis of OpenSSL's Random Number Generator和参考资料值得一读。

生成高熵随机数的能力对于生成密钥、初始化向量和密码操作的安全性所依赖的其他值至关重要。

这篇文章,改进 Ubuntu 14.04 LTS 云实例中的随机种子,关于 Ubuntu 为改进云中的熵所做的努力,更详细地描述了问题和可能的解决方案(花粉):

问:所以我的操作系统在第一次启动时会生成一个初始种子?答:是的,但计算机是可预测的,尤其是虚拟机。计算机本质上是确定性的,因此不善于产生随机性 真正的硬件可以提供质量熵 但是虚拟机基本上是彼此的克隆

Ubuntu 解决方案可能仍然无法满足 OP 的要求,因为它是“熵即服务”解决方案,但是(根据开发人员的说法)它是“快速、高效和可扩展的”。

要从理论转向实践,如果您有兴趣评估您的 PRNG 有多好,请查看Prangster :

现在我们的目标是确定产生给定伪随机输出样本的种子,并在此过程中确定使用不安全的 PRNG 并准备攻击使用它的应用程序。这是 Prangster 工具的主要功能;它所需要的只是输出和正确的 PRNG 和字母表

.

在像 AWS 这样的云环境中,如果您想在实例上本地生成高质量的随机数,您会遇到一些棘手的情况,因为引发了诸如 @michaelok 之类的问题。

相反,您应该考虑 AWS Key Management Service - 这正是它的设计目的。它使用简单的 API 封装了强大的硬件安全模块,您只需调用像GenerateRandom这样的 API 。API 使用与所有 AWS 服务相同的 IAM 安全模型进行保护。

我确信其他云也有类似的功能。

关于/dev/randomor有很多误解和神话/dev/urandom一般来说,使用/dev/urandom总是足够好并且/dev/random仅适用于偏执狂是不正确的。

这里的关键是在您开始生成数字之前在实例的生命周期内收集的熵总量。这才是最重要的。在实例生成(来自 AMI)之后,随机生成器需要积累足够的熵来开始产生不可猜测的数字。

一旦有足够的熵,您就可以从/dev/urandom. 但是,如果收集的熵还不够,那么除了首先获取它之外没有其他解决方案。

/dev/random减少熵的计数器有点偏执即使您公开了任何数量的先前生成的数字,您也无法猜测下一个生成的数字,这是一个好的 rnd 生成器的必备品为了实现这一点,生成器使用的结构与您在加密算法(AES、SHA 等)中找到的结构完全相同。因此,如果您不相信您的 rnd 生成器,那么您就无法相信您的加密。