我有一个具有以下用例的 Web 应用程序:
- 用户使用用户名和密码创建帐户 - 哈希密码存储在数据库中。
- 用户登录(跨会话持续存在)——登录令牌存储在 cookie 中。
- 用户输入和提交文本数据——数据存储在数据库中,但是是敏感的,即使数据库被破坏也不应该暴露。
- 只有(登录的)用户才能读取提交的数据,其他任何人都无法读取。
- 为方便起见,用户不需要输入任何密码来加密/解密数据。
这可行吗?数据应该如何加密?
我有一个具有以下用例的 Web 应用程序:
这可行吗?数据应该如何加密?
您可以使用密钥派生函数将用户的密码转换为加密密钥。然后,您将使用加密安全的伪随机数生成器来生成单独的密钥来加密用户的数据。然后,您将使用派生密钥来加密生成的密钥。然后可以将生成的数据加密密钥密文安全地存储在数据库的用户表中(如果您愿意,可以将字段称为“encryptedkey”)。这样,用户的密码将成为解密用户加密密钥的手段。实际加密数据的密钥仅被解密足够长的时间以解密它加密的数据。您需要将该密钥存储在会话中,以避免在每次解密时都需要向用户询问密码。
或者,您可以将密钥加密密钥存储在密钥管理服务中,例如 Amazon AWS 提供的服务。这样,您将仅使用对密钥的引用通过 TLS 从 Amazon 检索密钥。当然,在这种情况下,您仍然需要将 KMS 的身份验证凭据存储在架构中的某个位置,可能是在远程检索的高度安全的配置文件中。
随机数生成器 ⟶ 帮助创建密钥 #1。
此密钥会加密您的数据。它随着时间的推移保持不变。您必须在用户首次注册时生成此密钥。使用 CSPRNG(密码安全的伪随机数生成器)来确保足够的随机性和不可预测性。
密码 ⟶ 使用 PBKDF2 转换为密钥 #2。
这个密钥,密钥#2,用于加密密钥#1。您需要在用户会话中保留密钥 #2。将密钥#1 的加密形式存储在用户表中的一个名为(可能)“加密密钥”的字段中。
更改密码
每当用户更改密码时,您只需再次执行第 2 步,而不是重新加密所有数据。只需将新密码转换为密钥(密钥#2),重新加密密钥#1,并覆盖密钥#1 的加密形式的旧值。
加密/解密数据
当用户登录后,执行步骤#2。将密码转换为密钥后,只需解密密钥 #1。现在您已经解密了 Key #1,您可以使用 Key #1 来加密和解密您的数据。
不确定这是否可以作为评论有效,而不是答案:乐于变得更好。
唯一的目的是提供@vrtjason 接受的答案的可视化表示,因为这包括许多场景并涉及使用几个(加密)密钥。干得好:
为了完整起见,此类协议中涉及的密钥在文献中扮演的角色如下:
高温高压