仅当您不以某种方式信任服务器并且不想向其显示“实际”密码(人类用户记住的密码)时,客户端上的散列才有意义。为什么您不想将密码显示给该密码有任何用途的站点?因为您在其他地方重复使用了密码!现在这通常很糟糕,但是有一个相对安全的版本,它体现在无数浏览器扩展或书签中,例如这个或那个(我不保证它们的质量)。这些是人类用户记住“主密码”的工具,从中生成特定于站点的密码,使用站点域名作为一种盐,以便两个不同的站点获得不同的密码。
虽然这种情况是有道理的,但使用服务器本身发送的 Javascript 来做这件事就没有意义。事实上,散列密码客户端的关键在于服务器可能具有敌意(例如被攻击者破坏),因此该服务器发送的 Javascript 代码至少是可疑的。您不想在某些恶意 Javascript 中输入您宝贵的密码...
客户端散列的另一种情况是慢散列。由于根据定义,密码很弱,因此您希望阻止字典攻击。您假设坏人获得了服务器数据库的副本,并将在他自己的机器上“尝试密码”(有关此问题的一些讨论,请参阅此博客文章)。为了减慢对手的速度,你使用了一个固有的慢散列过程(例如bcrypt),但这会使每个人的处理速度变慢,包括服务器。为了帮助服务器,您可能希望卸载客户端上的一些工作,因此至少在客户端浏览器中运行的一些 Javascript 代码中完成部分工作......
不幸的是,Javascript 在这种工作上非常慢(通常比体面的 C 代码慢 20 到 100 倍),并且客户端系统将无法为散列工作做出很大贡献。这个想法是合理的,但必须等待更好的技术(尽管它可以与Java客户端一起使用:对于一个体面的 JVM,优化的 Java 代码比优化的 C 代码慢大约 2 到 4 倍,用于哈希作业)。
总而言之,从服务器本身发送的 Javascript 代码中进行客户端密码散列并没有真正好的案例。只需通过 HTTPS 隧道“按原样”将密码发送到服务器(登录页面、表单目标 URL 以及任何受密码保护的页面,都应通过SSL 提供,否则您将面临比使用密码)。