我们有一个网站,用户需要登录才能访问特权信息。显然我们正在使用 SSL,但我也想避免明文密码意外地出现在服务器日志中,或者管理员的视线。因此,我想使用 Javascript 实现客户端散列。
此外,我想避免泄露具有相同密码的用户对,因此使用特定于用户的盐。最后,我想在混合中添加一个随机挑战(又名随机数),以确保窃听者*不能使用最终哈希作为新的“密码”。在开始密码散列之前,我将额外往返网络服务器以获取盐和挑战。*) 是的,我们正在使用 SSL,但作为深度防御,我希望使实施尽可能可靠。
尤其是挑战具有挑战性。我所知道的唯一可行的实现是首先计算最终的密码哈希(使用 bcrypt、scrypt 或 PBKDF2),然后使用挑战进行一轮额外的 sha256_hmac。在服务器端,我们从数据库中获取密码哈希并执行相同的附加 sha256_hmac 并比较结果。
但是,以上内容意味着完整的密码哈希计算必须在 Javascript 客户端完成,因为挑战中的哈希应该始终是最后一步。在旧版(?)iPhone 3G 上,只能在 2 秒内完成 6 轮 bcrypt 或 5000 轮 PBKDF2-SHA256,这是我们可以容忍的最大延迟。
问题 #1:我是否正确,现在 bcrypt 应该至少 12 轮,而 PBKDF2-SHA256 至少 5000 轮?所以我应该选择5000轮的PBKDF2-SHA256?
问题 #2:是否存在可以在流程早期运行的质询-响应机制(例如,在一次散列密码上),所以我可以将 bcrypt/PBKDF2 加固留给网络服务器?
问题#3:假设不存在这样的质询-响应机制,是否最好放弃我的质询-响应要求,只应用用户特定的盐客户端并彻底强化服务器端?与使用挑战-响应机制和更少的回合相比,这会导致整体更强大的系统吗?
编辑:总结下面关于客户端散列安全性的长期评论:普遍意见似乎是增加的复杂性是不值得的,最好把精力放在审计服务器端代码上并限制不受信任的员工的服务器端访问。