在这里跟进我的问题,我现在需要安全地存储对称密钥。 查看选项后,听起来这可能是一个不错的选择:
建立:
数据库中有一个表,其中包含两个字段
php_key - stores a symmetrically encrypted symmetric key that is used for OTHER tables
php_key_hash - stores a hmac of the symmetric key
其他表格(如其他帖子所述(:
last_name - symmetrically encrypted value encrypted with key after being unencrypted from php_key
last_name_hash - hmac of last_name
登录/安全保护密钥:
1(用户登录 - (不相关的(用户/通行证只是存储在数据库中(通行证是hmac(
2(登录后,用户会看到一个屏幕,他们必须在其中输入另一个密码 - 此密码将与公司的所有员工共享(只有5名员工很容易记住(。 我们调用此键 1。
3( 该密码已执行 hmac,并与数据库中的php_key_hash进行比较。
如果失败,我可以在这里错误用户。
4(如果匹配,则下拉php_key,使用相同的密码解密,将其存储在会话变量中。
此时,密钥存储在服务器上的内存中,并在用户注销时销毁。我们调用此键2。
在此正常解密字段之后,就像在另一篇文章中一样发生
这对我来说似乎真的很安全,因为
1( key2 存储在与 Web 服务器不同的服务器上
2( key2 本身是加密的 - 它永远不会以纯文本形式存储
3( key1 不在代码、文件系统或数据库中的任何地方 - 它只在员工的脑海中知道
4(您基本上必须登录该站点两次(一次使用您的登录名,再次使用key1(
5(会话变量的使用意味着key2只存储在内存中,只存储在服务器上,并在会话结束后销毁
6( 如果我们需要更改密码,我可以随时重新键入 key1 - 例如,如果员工离职或我们认为密码已泄露
潜在问题又名我的问题(最后(
首先,我绝不是安全专家,因此为什么我只想听取在安全方面比我更好的人的意见:)
1(我可能会将加密的对称密钥(key2(存储在用于解密其他字段的同一数据库中。我不认为这是一个问题,因为它本身是加密的?
2( 将对称密钥 (key2( 存储在会话变量中 - 人们浏览 RAM 的潜在问题? 也许最好只是将 key1 存储在会话变量中,然后每次都必须进行双重解密(但可能很慢(?我是不是过于谨慎了?
好的,我想我现在明白你的意思了。我假设你的意思是:
key1 = PBKDF2(password, salt, many_iterations)
php_key_hash = HMAC(key1, salt)
当你说HMAC的密码时,我假设你的意思是PBKDF2有很多次迭代(例如几秒钟(。无论如何,要回答您的 2 个问题:
1(将加密key2
保存在key2
加密的数据旁边是可以的。事实上,AWS KMS
以这种方式工作,除了它们对每个加密使用不同的key2
。如果一个key2
受到损害,则只有其相应的数据会受到损害(而不是整个数据库(。它使密钥轮换更简单。
2(如果您将key1
保存在RAM中而不是key2
中,那将无济于事:如果有人设法从RAM获取key1
,您可能会假设他们也可以访问数据库中的php_key
,并且能够解密key2
。如果你想防止这个问题并且不希望密钥在RAM中,你应该考虑HSM(key2
普通地永远不会离开HSM(。如果没有 HSM,key2
必须在某个时候位于 RAM 中。