我的理解如下:
为了安全地存储密码(例如在数据库中),您使用为此目的而设计的散列算法(设计速度较慢,例如 bcrypt),并且您为每个密码使用唯一的盐。这使得有权访问数据库的攻击者恢复密码变得困难/缓慢,因为他们不能使用彩虹表,并且每次暴力尝试都比简单的 md5 或 sha1 花费更多时间。
为了通过纯文本协议(即非 SSL)安全地验证密码,服务器向客户端发送一个随机数,客户端将密码和随机数(可能还有时间戳)结合起来,在它们上运行散列算法,然后将该哈希传输到服务器,服务器运行相同的算法并进行比较。这避免了以纯文本形式发送密码,并且也使得重放攻击不可能,只要服务器不能被欺骗两次接受相同的随机数。
问题是,对于身份验证部分,服务器需要知道实际的明文密码。所以你不能像#1那样安全地存储它们。
现在,服务器可以将盐传输给客户端,客户端可以先计算加盐、散列的密码,然后执行#2。但是,加盐哈希密码实际上变成了明文密码,所以你仍然没有真正的#1。
所以我的问题是,有没有办法同时做#1和#2?