首页 > 解决方案 > 用密码与哈希加密密码

问题描述

我正在为我们的一个内部工具构建身份验证服务,在查看了各种文章之后,我可以将它们总结为

我知道任何可能导致明文密码的东西都是不好的,但我只是想知道为什么没有人使用密码来加密密码,比如说,AES256?我的意思是,由于它是对称加密,它没有任何私钥。因此,即使发生泄露,也无法取回实际密码。加盐密码并用密码本身加密有什么问题?

标签: securityauthenticationencryptionaes

解决方案


加盐密码并用密码本身加密有什么问题?

这是一个非常快速的操作,可以非常快速地测试(即“破解”)密码。使用 SHA-2 之类的算法进行简单散列也是如此。处理密码的正确方法是加盐和拉伸它们(而不是简单地散列它们)。“拉伸”意味着通过称为 KDF(密钥派生函数)的时间密集型算法(例如 PBKDF2 或 scrypt)运行它们。

同样重要的是,人工生成的密码无论如何都不能直接用于使用 AES 进行加密。AES 需要一个精确大小(16、24 或 32 字节)的密钥,并且为了确保密钥在整个密钥空间中完全随机的安全性。人工生成的密码很少是正确的长度,并且在整个密钥空间中永远不会随机(既因为人类是较差的随机值生成器,又因为 32 个可键入字符只是所有可能的 32 字节密钥的一小部分;要正确键入这样的密钥, “密码”需要将近 40 个字符长,并且使用通用键盘上的所有大写/小写字母、数字和符号完全随机输入)。

将人工生成的密码转换为密钥的正确方法是通过 KDF 运行它(这就是为什么它被称为“密钥派生函数”)。如果您只关心身份验证(验证用户是否知道正确的密码),那么添加额外的加密步骤没有任何价值。您可以只使用拉伸键。

扩展密码(KDF 的输出)是唯一应该发送到服务器的内容。然后,服务器应该使用 SHA-2 再对该值进行一次散列并存储它。这样,呈现给服务器的密钥与存储在数据库中的密钥不同,即使数据库被盗,也无法用于向服务器进行身份验证。


推荐阅读