【问题标题】:Cryptography: best practices for keys in memory?密码学:内存中密钥的最佳实践?
【发布时间】:2010-11-18 19:11:33
【问题描述】:

背景: 我在数据库中使用 AES(即对称加密)加密了一些数据。在(假定的)安全且隔离的 Linux 机器上运行的服务器端应用程序使用此数据。它从数据库中读取加密数据,并写回加密数据,只处理内存中未加密的数据。 因此,为了做到这一点,应用程序需要将密钥存储在内存中。

问题是,有什么好的最佳实践吗?保护内存中的密钥。

一些想法:

  1. 将其保存在不可交换的内存中(对于 linux:将 SHM_LOCK 设置为 shmctl(2) ?)
  2. 将密钥拆分到多个内存位置。
  3. 加密密钥。用什么以及如何保证...key key..的安全?
  4. 每次需要时从文件中加载密钥(速度慢,如果作恶者可以读取我们的内存,他可能也可以读取我们的文件)

key 可能泄露的一些场景:evildoer 获取了 mem dump/core dump;错误的代码边界检查导致信息泄露;

第一个看起来不错,而且很简单,但是剩下的呢?其他想法?任何标准规范/最佳实践?

感谢您的任何意见!

【问题讨论】:

    标签: memory cryptography key aes


    【解决方案1】:

    一切都取决于您的偏执程度和关键/数据的敏感性。在极端情况下,只要您在内存中有未加密的密钥,就可以使用coldboot 技术检索它。 frozencache 有一个有趣的发展,试图打败它。我只是随便读了一遍,没有在实践中尝试过,但这似乎是一种有趣的尝试方式。

    尽管摘下锡箔帽,但 - (1)、(2)、(3) 似乎是合理的。 (4)不会因为你提到的原因而精确切割它。 (不仅速度很慢,而且假设您读入堆栈,在不同的堆栈深度下,键可能不止一次可见)。

    假设解密的数据是值得的,并且它会在可交换的内存中,你当然也应该加密交换本身。此外,根、/tmp 分区也应该加密。这是一个相当标准的设置,在大多数操作系统指南中都很容易找到。

    然后,当然,您希望确保机器本身的高水平物理安全尽量减少它执行的功能 - 运行的代码越少,暴露的越少。您可能还想看看如何绝对最小化远程访问这台机器的可能性 - 即使用基于 RSA 密钥的 ssh,这将被另一个主机控制的另一个 ACL 阻止。 portknocking 在能够登录到第二台主机之前,可以用作额外的身份验证向量之一。为确保如果主机受到威胁,则更难将数据取出,请确保该主机没有与互联网的直接可路由连接。 一般来说,获取敏感数据越痛苦,有人去那里的机会就越小,但这也会让普通用户的生活变得痛苦 - 所以需要有一个平衡。

    如果应用程序很严重并且风险很高,最好构建更明确的整体威胁模型,看看您可以预见哪些可能的攻击向量,并验证您的设置是否有效处理他们。 (不要忘记包含human factor :-)

    更新:确实,您可以使用专用硬件来处理加密/解密。那么您不必处理密钥的存储 - 请参阅 Hamish 的答案。

    【讨论】:

    【解决方案2】:

    如果您非常重视安全性,那么您可以考虑使用单独的加密子系统。最好是经过FIPS 140-2/3 认证的 (list of certified modules)。
    然后密钥保存在防篡改内存中(不可提取),所有加密操作都在加密边界内执行。
    昂贵,但对于某些必要的应用程序。

    【讨论】:

    • 我相信 Mozilla 的 NSS 库会做到这一点,而且它是免费的
    • +1,很好。我不知何故设法忘记了专用加密货币:-)
    【解决方案3】:

    也不要忘记核心转储和内存被换出的威胁!

    在 POSIX(如 Linux)和 Windows 系统上,如果您使用 C 语言,有一些技术可以防止这种情况发生 - 请参阅 CERT 安全编码标准中的此部分:

    MEM06-C. Ensure that sensitive data is not written out to disk

    【讨论】:

      【解决方案4】:

      最大的问题是程序必须从某处读取密钥。除非您在每次服务器重新启动时都接受直接键盘输入,否则它几乎必须存在于磁盘上的某个位置。

      一般而言,您必须假设作恶者无法访问根级操作系统或硬件,因为在这种情况下,即使密钥仅在 RAM 中,他们最终也会设法获得密钥。

      因此您假设服务器的操作系统是安全的。但是假设有人可以来偷硬盘驱动器,所以启动服务器会给他们钥匙。然后让服务器向另一台服务器请求一半的密钥,远程服务器验证请求(使用 ip、私钥/公钥对)并提供一半的密钥。那么你的服务器就有一个完整的密钥,而远程服务器永远不会超过一半。在我看来,这似乎提高了保护水平。

      【讨论】:

        【解决方案5】:

        我会看什么

        在处理键时执行。他们对此类安全问题非常偏执......

        【讨论】:

          【解决方案6】:

          使用“超级超级用户”硬件内存是理想的。所有英特尔 Mac 都有这个 SecureEnclave 内存区域,它还包括硬件中的 AES 解密,因此应用程序和操作系统永远无法访问原始私钥。当机器启动时,输入密码(可选),SecureEnclave 将其冷闪存加密版本的密钥解密到主操作系统无法访问的 RAM 区域。

          不错的副作用是硬件加速加密:我在一个新格式化的加密磁盘上对我的 PCIe 存储进行了 600 MB/秒的写入基准测试。

          在云中,Amazon 拥有这项 AWS Key Management Service (KMS) 托管服务,让您可以轻松创建和控制用于加密数据的加密密钥,并使用 FIPS 140-2 验证的硬件安全模块来保护密钥的安全性:https://aws.amazon.com/kms/

          【讨论】:

            猜你喜欢
            • 2014-12-18
            • 2011-09-23
            • 2014-07-28
            • 2022-11-03
            • 1970-01-01
            • 1970-01-01
            • 2019-07-30
            • 2017-04-20
            • 2013-05-29
            相关资源
            最近更新 更多