bcrypt 不适用于这种类型的客户端散列
bcrypt 的一个关键特性是,当使用相同的明文运行两次独立的时间时,大多数实现会产生不同的哈希值。这是由于使用了盐,它的设计目的是难以查看两个不同的用户是否具有相同的密码。
相比之下,登录表单每次都需要接收相同的数据。毕竟,您将如何验证用户今天输入的密码与他们昨天输入的密码相同?
因此,您有一个设计用于每次生成不同数据的算法,并且您将其输入到需要验证数据每次都相同的应用程序中。这可能表明该算法没有按预期使用。
理想情况下,您应该做的是使用 bcrypt 对服务器上的密码进行哈希处理。这就是 bcrypt 的设计目的:在明文不在内存中时保护用户密码,这是迄今为止最常见的状态(例如,如果实施正确,DB 转储只会显示散列密码,而不是明文)。
我个人也看到了客户端散列的一些价值,因为它确实有助于防止可以嗅探流量(或具有服务器访问权限)的攻击者。但是,我不知道有一种方法可以使客户端散列与服务器端 bcrypt 一样安全——这就是为什么您仍然应该使用服务器端 bcrypt。
如果您必须使用 bcrypt 客户端,请使用静态盐
如果您打算使用 bcrypt 对登录表单进行客户端哈希处理,并且希望它成为 MD5 的替代品,则需要使用静态盐。特别是如果您通过 SHA1 传递它,因为这会破坏 bcrypt 盐以及散列数据本身。
当然,这确实打破了 bcrypt 的几个设计假设(例如始终使用随机盐)。
我个人建议使用用户名作为盐(这样很难判断两个不同的用户是否具有相同的密码);但是,我不知道在这种情况下对盐渍进行的任何研究。
AES(或任何对称密码)在这里也没用
请记住,AES 是一种对称算法,这意味着您需要相同的密钥来解密和加密数据。
这对你意味着什么?好吧,您可能已经在 JavaScript 源代码中获得了您的加密密钥,该源代码将提供给访问您的登录页面的任何客户端。AES 是一种对称密码,因此您的加密密钥(与解密密钥相同)应保密。换句话说,你的私钥是众所周知的——它在这一点上实际上没有提供任何安全性。
您应该改用公钥加密技术,例如 PGP 或 HTTPS(从技术上讲,HTTPS 使用混合方法)。说真的,只需使用 HTTPS,除非您的组织出于某种原因拒绝让您拥有 SSL 证书。请记住,PGP 并不能真正防止主动 MITM 攻击,但它至少可以防止窃听。