注意事项:我知道安全密码存储的好答案是scrypt或bcrypt。这个问题不是为了在实际软件中实现,而是为了我自己的理解。
假设 Joe Programmer 的任务是将最终用户密码安全地存储在 Web 应用程序的数据库中;或将密码存储在磁盘上以登录某个软件。他很可能会:
$password
从最终用户处获取。- 创建
$nonce
为大约 64 或 128 位大小的随机值。 - 一起创建
$hash = SHA256($nonce$password)
并存储在数据库中。$nonce
$hash
问题一:
为什么以下内容没有明显优于上述内容?
- 创建
$long_string
一次且仅一次。将此作为常量存储在应用程序代码中。$long_string
fx 可以是 2 KB 的随机字符。 $password
从最终用户处获取。- 创建
$mac = HMAC-SHA256($long_string)[$password]
(即使用最终用户密码作为密钥创建 MAC)并将其存储$mac
在数据库中。
我想 HMAC 有以下好处?
- 碰撞少了?
- 它在计算上比普通散列更昂贵?(但当然不是 scrypt 附近的任何地方。)
- 为了在合理的时间内成功进行蛮力攻击,攻击者需要获得对两件事的访问权:1)数据库,
$mac
存储位置,2)应用程序代码,原始$long_string
存储位置。这比散列函数更好,攻击者只需要访问数据库?
但是,似乎没有人建议使用 HMAC,所以我一定是误解了什么?
问题二:
添加盐值的含义$nonce
是什么?
- 创建
$long_string
一次且仅一次。将此作为常量存储在应用程序代码中。 $password
从最终用户处获取。- 创建
$nonce
为大约 128 位大的随机值。 - 创建并
$mac = HMAC-SHA256($long_string)[$nonce$password]
存储在数据库中。$nonce
$mac