我正在构建一个提供用户登录的网站。为此,我目前正在研究处理身份验证的好策略。
我现在是怎么做的
我目前的概念是以目前似乎已达成的共识为蓝本的。密码用 64 字节/dev/urandom
的 SHA-512加盐,然后用 100 轮 SHA-512 散列。每轮结束后,原始密码与结果连接,然后输入下一轮。当用户想要登录时,他们将他们的凭据发送到服务器,然后重复描述的过程(显然使用相同的盐)并与数据库中的哈希值进行比较。
这个策略对我来说似乎足够安全(如果我错了,请纠正我,它基本上只是阅读大量在线指南和观看 YouTube 视频的结果)。但是,我认为它有一个重大缺陷,即客户端必须以纯文本形式将密码发送到服务器。是的,我很自然地使用 HTTPS,但是,如果连接因某种原因被破坏,密码也是如此。
替代概念
所以我想到了一个完全不同的方法:使用 PGP 密钥。当用户注册时,他们会生成一个 PGP 密钥对,使用他们选择的密码加密私钥并将其发送到服务器。当他们想再次登录时,服务器会生成一串随机字符并使用公钥对其进行加密。然后将加密的随机字符串和密钥对发送给客户端,客户端需要再次解密以证明他们拥有私钥的密码。
这种方法可以防止密码通过网络传输,甚至允许用户之间进行端到端加密聊天等很酷的东西。我能找到的唯一缺点是服务器必须向基本上任何请求它们的人提供加密的私钥,这使得暴力攻击更容易。我可以通过在客户端运行计算成本高昂的密钥扩展算法并使用其结果来加密私钥来缓解这种情况。
但我仍然不完全相信整个事情,所以我很想听听你的反馈,看看这是否是一个好主意,或者我是否应该坚持我现在的做法。
编辑:
根据一些答案,我认为我的问题有点误导。我的要求是,无论用户使用什么设备或之前是否登录过该设备,用户都需要为成功的身份验证提供唯一的东西是他们的用户名/密码,而不是其他任何东西。