我正在设计一个 REST API,但在验证用户的安全性方面存在一些问题。对于身份验证,我不希望密码以纯文本形式通过网络发送。
为了绕过这个问题,我可以发送密码的 SHA-256 哈希(用户名为 salt),因此密码永远不会以纯文本形式发送。在我的数据库中,我将存储以下哈希值:SHA256(password + salt),如果两个哈希值匹配,我将进行比较。
此选项的问题是我将使用快速哈希算法计算哈希,并且盐不是随机的。
在安全方面,最佳实践是使用慢速签名算法,带有随机盐(如 bcrypt)。
慢速算法不是问题,我可以在客户端使用 bcrypt,但是对于 salt 我不知道该怎么做:
- Bcrypt 需要一个定义大小的盐,所以我不能输入用户名
- 如果我使用的是随机盐,客户端如何在计算密码哈希之前知道这个盐的值?
所以我可以看到 3 个选项,但没有一个令人满意:
- 我以纯文本形式发送密码(我正在使用 SSL)并将 bcrypt 存储在数据库中 => 仍然容易受到中间人的攻击
- 我使用 SHA256 并发送盐为用户名的哈希(仍在使用 SSL)=> 数据库中的哈希不太安全
- 我使用 bcrypt,我有一个两步过程:我要求给定用户的 salt,然后发送该用户的哈希(仍然使用 ssl)=> 通过尝试使用其他用户名登录我可以获得他的 salt,而不是惊人的
有人有更好的解决方案或一些建议吗?