对称加密密钥是如何存储的?

信息安全 密钥管理
2021-09-02 07:36:39

如果您有一个在移动设备(例如智能手机)和服务器之间通过SRP 协议协商的对称密钥,那么在每一侧保存这个生成的密钥的安全方法是什么?

在客户端,您可以使用 PBKDF2 或类似的密钥派生函数来生成密钥,然后在使用对称密钥之前对其进行加密/解密。这会被认为(可接受的)安全吗?

服务器端有哪些可能性?将这样的密钥存储在数据库中的安全过程是什么?

例如,亚马逊如何存储用于 S3 查询字符串身份验证的对称密钥?(有关信息:在 S3 上,您可以限制对存储对象的访问,以便只有具有有效签名(使用 HMAC 创建)的请求才能被授予对所请求(受限)对象的访问权限)

2个回答

密钥(对称或非对称)通常存储在某种加密介质中,例如密钥库或加密数据库。密钥库的具体示例是 JKS(Java 密钥库),数据库是 SQLCipher。此加密介质使用主密码保护,读取/写入它是必需的。SQLCipher 将首先使用 PBKDF2 搅动密码,以确保它具有足够的熵和计算成本。

主密码存储位置的问题当然会影响系统的安全性。对于客户端来说,期望用户记住它是最好的选择。对于服务器端,可以使用硬件安全模块 (HSM)来保护密钥,例如亚马逊的密钥管理服务

在客户端,您可以使用 PBKDF2 或类似的密钥派生函数来生成密钥,然后在使用对称密钥之前对其进行加密/解密。这会被认为(可接受的)安全吗?

这实际上取决于几件事:

1. 什么是威胁模型?

你想阻止谁攻击你?民族国家?嫉妒的另一半?脚本小子?此人是否可以物理访问客户的设备?等等。

2.您使用什么作为 KDF 的输入(在您的示例中为 PBKDF2)?

希望 KDF 的输入不会保留在设备上(除了盐和轮,你可以把它们留在周围),而是一些足够的熵,用户被迫输入一次(例如,密码)然后在不再需要时从内存中擦除。

3. 您如何加密和存储密钥?

如果有可用的受信任的专用硬件(例如,TPM 或 HSM [假设您信任那些]),那么它们将为您提供一种存储对称密钥的方法(有些将它们存储在专用硬件上,有些使用存储的密钥对其进行加密)在硬件上,但将生成的密文存储在您的存储设备上)。如果没有这样的硬件可用,那么您通常会将密钥存储在密钥库中,该密钥库基本上是一个以加密方式存储密钥的文件(或文件集)。已经有几种实现方式,但如果您要推出自己的实现方式(我推荐),那么您需要考虑如何保护加密密钥的机密性和完整性。需要考虑的一些事项是:

  • 每个要加密的密钥会用不同的 KEK 包装吗?
  • 您将如何得出每个 KEK?
  • 您将使用哪些算法/模式?
  • 你需要什么样的性能?

4. 当你不再需要它们时,你会如何处理内存中的键?

一旦不再需要每个密钥的每个副本,都应该从内存中擦除它们。关于如何做到这一点存在争议,从只是在内存中的字节上写入一堆零,到做更多涉及多次传递的花哨的事情,每一次将不同的字节写入内存中的密钥区域。你做什么应该取决于你的威胁模型。

服务器端有哪些可能性?将这样的密钥存储在数据库中的安全过程是什么?

服务器端有非常相似的选项。理想情况下,服务器将使用 HSM 并将密钥存储在其中(有关更多详细信息,请参见上面的 #3),并且您的服务器端应用程序将永远无法访问原始密钥字节(只有 HSM 可以)。在数据库中,您只需存储密钥的别名(您可以使用 HSM 提供数据库记录和别名之间绑定的完整性)。

例如,亚马逊如何存储用于 S3 查询字符串身份验证的对称密钥?

我不确定 Amazon 专门针对 S3 的查询字符串身份验证做了什么,但我知道他们提供了Cloud HSM 服务