关于安全性:使用密码哈希来加密私钥

Using hash of password to encrypt private key

我正在开发一个需要加密敏感信息的Web应用程序。我的计划是使用AES-256,其中私钥由用户密码的哈希加密。为了进行身份验证,我需要存储密码的散列值,但显然不能用它来加密私钥。我目前的想法是使用bcrypt生成一个密钥,用于加密私钥。对于身份验证,我的想法是使用bcrypt简单地散列密码,然后再次使用bcrypt散列密码,然后将散列存储在数据库中。因为这是一种方法,所以不应该有任何方法使用存储的哈希来解密私钥?这样做是否有明显的安全问题,我可能会错过?

我的另一个想法是使用两种不同的加密算法,例如使用bcrypt散列来加密私钥和存储用于身份验证的sha-2散列。

谢谢你的帮助。


我建议在这种情况下使用pbkdf2。您可以使用两种不同的盐类,一种派生对称密钥,另一种派生要存储的密码哈希。salt应该包含一个确定性部分,用于区分两个不同的用例,以及一个随机部分-参见。此注释:

Otherwise, the salt should contain data that explicitly
distinguishes between different operations and different key
lengths, in addition to a random part that is at least eight
octets long, and this data should be checked or regenerated by
the party receiving the salt. For instance, the salt could have
an additional non-random octet that specifies the purpose of
the derived key. Alternatively, it could be the encoding of a
structure that specifies detailed information about the derived
key, such as the encryption or authentication technique and a
sequence number among the different keys derived from the
password. The particular format of the additional data is left
to the application.

正如评论中所提到的,由于典型密码的熵很差,一个普通的、盐渍的sha-2可能还不够。


不要使用哈希加密AES密码。salted哈希只能用于身份验证。当用户登录时,您有他的密码。使用此密码加密(第一次)和解密(稍后)AES密钥,然后忘记密码。


建议:使用两种不同的盐。当用户输入密码时,将其与随机salt连接起来,并将其散列以用于密码识别例程。使用不同的salt,然后再次将其散列为aes加密密钥。根据你想要的东西有多安全,你也可以扩展散列。

实际上,您有:

1
2
3
storedPasswordCheck = SHA256(password + salt1);

AESkey = SHA256(password + salt2);

当然,AES密钥不会存储,但会根据需要从用户密码重新生成。您将需要两个单独的盐,最好每个至少128位,为每个用户存储。