使用密码哈希来加密私钥

6
我正在开发一个Web应用程序,需要加密敏感信息。我的计划是使用AES-256算法,其中私钥由用户密码的哈希值加密。我需要存储密码的哈希值以进行身份验证,但显然不能用相同的哈希值来加密私钥。我的想法是使用bcrypt生成一个用于加密私钥的密钥。对于身份验证,我的想法是使用bcrypt简单地哈希密码,然后再次使用bcrypt哈希该哈希值,然后将该哈希值存储在数据库中。因为它是单向的,所以不应该有任何方法可以使用存储的哈希值解密私钥。我可能忽略了做这件事情时存在的任何明显安全问题吗?
我的另一个想法是使用两种不同的加密算法,例如使用bcrypt哈希来加密私钥,并存储SHA-2哈希以进行身份验证。
谢谢你的帮助。

如果这里没有人能给你一个明确的答案,你可以尝试前往http://crypto.stackexchange.com/。 - Joachim Isaksson
3个回答

2

不要使用哈希算法来加密AES密码。盐值哈希仅用于身份验证。当用户登录时,您拥有其密码。使用此密码来加密(第一次)和解密(以后)AES密钥,然后忘记密码。


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

否则,盐应包含明确区分不同操作和不同密钥长度的数据,除了至少为八个八位组的随机部分外,并且接收盐的一方应检查或重新生成此数据。例如,盐可以具有指定派生密钥目的的附加非随机八位组。或者,它可以是编码结构,其中指定派生密钥的详细信息,例如加密或身份验证技术以及从密码派生的不同密钥中的序列号。附加数据的特定格式留给应用程序。

因为密码的熵通常很低,所以纯盐SHA-2可能不足够,正如评论中提到的那样。

1
建议:使用两种不同的盐。当用户输入他们的密码时,将其与一个随机盐连接起来,并对密码识别例程进行哈希处理。再次使用不同的盐进行哈希以获取AES加密密钥。根据您所需的安全级别,还可以拉伸散列。

实际上你有:

storedPasswordCheck = SHA256(password + salt1);

AESkey = SHA256(password + salt2);

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

1
把哈希转换应用到源密码上并不能比直接在哈希中使用用户密码获得更多的安全性。也就是说,哈希函数无法生成比用户原始密码中更多的熵(这适用于任何哈希函数)。 - Billy ONeal
我几乎认为你甚至不需要在AES密钥上加盐——无论如何,密码仍然不会以明文形式保存。 - Billy ONeal
人们会选择可猜测的密码:"secret","qwertyuiop","password123"。他们也会选择容易记住的密码,这些密码易受尝试字典中所有单词的攻击。有密码破解程序可以利用这些漏洞。哈希算法可以防止此类情况发生,而盐可以防止预先准备好的彩虹表和其他离线攻击方法的简单使用。拉伸技术可以根据需要让攻击者变得更慢。 - rossum
1
不,哈希和盐值都不能防止与这些常见的“愚蠢”密码有关的任何问题。无论如何进行多么好的哈希或盐值处理,如果密码容易被字典破解,那么它就会很容易受到攻击。盐值可以防止彩虹表攻击,但对于AES来说并没有意义——彩虹表是用来破解哈希函数的,而不是块密码。哈希的优点在于明文密码不会被存储,但作为AES的输入,明文也不会被存储。 - Billy ONeal
感谢Billy和rossum的评论。它们非常有帮助,让我思考了我的方法。为了提供更多有用的背景信息,我正在使用PHP,并计划使用MCRYPT_RIJNDAEL_128进行加密算法。根据我所读的,为了获得AES-256的安全性,您需要一个256位的密钥。由于用户的密码可能不够长,我认为对密码进行哈希处理可以给我更长的密钥,从而更加安全。 - user1576169
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接