2012-10-25 58 views
2

客户端程序(通过它我无法控制)通过发送密码进行认证,散列为SHA1(password)。我很不愿意在我的数据库中存储使用SHA1的密码散列,所以我建议将数据库中的密码存储为散列为SHA256(SHA1(password))(其中密码使用PBKDF-2或类似的东西进行多次迭代散列)。使用SHA1作为链中最内部散列的散列

我的问题是:在这种情况下,使用SHA1的最内部散列值有什么不安全感?我意识到碰撞的可能性会增加,但由于这仅仅是用于在数据库中存储密码,所以我不认为我需要担心这一点。还有什么我失踪?

+2

对于这个问题(可能)更正确的答案,请尝试http://crypto.stackexchange.com/ –

回答

1

考虑在进行最终加密之前添加一行是唯一的盐。例如:

假设您收到W6ph5Mm5Pz8GgiULbPgzG37mj9g=(SHA1'd加密"password")。这与用户应该有一个唯一的密钥相关联,例如UserID和/或UserName。

我的建议 - 避免碰撞 - 将字节转换为Base64String(在C#中,这将是Convert.ToBase64String(byteVariable) - 然后将字符串连接到用户的唯一ID(使新字符串如下):

W6ph5Mm5Pz8GgiULbPgzG37mj9g=+103(我添加了+103以反映用户的ID) - 然后应用SHA256算法,这将产生:mNXRjWsKJ7V+BHbAuwJJ7neGT+V1IrLQSQXmb4Vv1X8= - 您可以将其存储在数据库中SHA256哈希 - 消除来自不太安全SHA1的冲突算法

而且 - 由于您使用的是单向加密 - 当您检查密码是否为在将来有效时,您只需在检查之前再次附加用户标识。

+2

PBKDF-2使用base64或其他任何冗余进行任何扩展。不过,添加一个盐 - 无论是用户的内部唯一ID还是存储在其记录中的不可变的内容 - 始终是一个好主意。 – SilverbackNet

+1

确定性数据(如用户ID)对Salt来说不是一个好的选择。发明自己的密码系统也不是 - 这就是PBKDF2和其他密码哈希原语存在的原因。 –

+0

感谢您的回答。然而,我想知道为什么我应该关心我是否碰到碰撞? – Neil

1

如果客户端总是向您发送相同的密码,只需SHA1散列,那么SHA1散列输出就是的密码,以达到所有意图和目的。对待它并以与任何其他密码相同的方式存储它,例如使用PBKDF2,SCrypt或BCrypt。