加盐密码哈希值
我正在尝试为 Web 应用程序创建一个登录系统,但我遇到了一些问题。我使用 sha2-512 哈希和 128 位随机盐将密码存储在数据库中。
然而,我目前使用 html 表单以纯文本形式将密码发布到我的应用程序中,无论是在创建帐户时还是在用户登录时。我知道这是错误的。
我需要在客户端对密码进行哈希处理吗?如果是这样,我如何考虑当前生成并存储在数据库中的盐?
注意:我这样做是为了学习不要在生产系统中使用
I am trying to create a login system for a web application, but I am stuck on a couple of points. I am storing the password in my database using a sha2-512 hash with a 128 bit random salt.
However I currently have the password posted in plain text to my application using a html form, both when the account is created and when the user logs in. I know this is wrong.
Do I need to hash the password in the client? If so how do I take into account the salt which is currently generated and stored on the database?
NOTE: I am doing this to learn not to use in a production system
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
![扫码二维码加入Web技术交流群](/public/img/jiaqun_03.jpg)
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
最好的选择通常是使用 SSL。如果您确实需要在客户端进行哈希处理,我会这样做:
这是安全的,因为它确保所传输的哈希值对于请求来说是唯一的(它使用单个请求随机盐),因此将来不能仅通过再次发送哈希值来伪造登录。向客户端发送存储的盐并不危险,因为假设密码破解者将有权访问存储的盐(如果他们可以访问数据库)。需要两个哈希值才能防止您将密码存储为明文。
The best bet is generally just to use SSL. If you did need to hash on the client side, this is how I'd do it:
This is secure because it ensures that the hash being transmitted is unique to the request (it uses a single-request random salt), so a login cannot be faked in the future simply by sending the hash again. It is not dangerous to send the client their stored salt, as it is assumed that password crackers will have access to the stored salt (if they get access to the db). Two hashes are required to prevent you from ever having to store the password as plaintext.
您应该使用 SSL 传输加密的密码,以便中间人无法拦截数据包并读取正在发送的凭据。即使您在客户端中预先对密码进行哈希处理,中间人仍然可以使用该值来伪造身份。
不过,真正让我担心的是 SHA-512 的使用。许多人使用加密哈希来存储密码,但流行观点忽略了一个非常重要的点:这些哈希被设计是为了快速。也就是说,成为 SHA(或类似)哈希的要求之一是能够在嵌入式硬件上快速对大型文档进行哈希处理。
这与您想要的密码存储完全相反,因为它允许高性能 GPU 上的专用例程以令人惊讶和可怕的速度暴力破解密码!
这就是为什么开发了一些专门构建的密码存储哈希的原因。我一直在使用的是 Bcrypt,它的速度足够慢,足以阻止暴力攻击,可调节以便将来配合更快的硬件,并且还有为您处理加盐的额外好处。
You should be using SSL to transmit the passwords encrypted so that a man-in-the-middle can't intercept the packets and read off what ever credential is being sent. Even if you pre-hash the password in the client, a man-in-the-middle can still just use that value to fake identity.
What really concerns me, though, is the use of SHA-512. A lot of people use cryptographic hashes for password storage, but popular opinion misses a very important point: These hashes were designed to be fast. That is, one of the requirements to become an SHA (or similar) hash is to be able to quickly hash large documents on embedded hardware.
This is the exact opposite of what you want for password storage, as it allows specialized routines on high performance GPUs to brute force passwords at a surprising and scary speed!
This is why some purpose built password storage hashes have been developed. The one I have been using is Bcrypt, which is slow enough to keep out brute force attacks, adjustable to couneract faster hardware in the future, and has the added bonus of handling the salting for you.
在客户端上对密码进行哈希处理需要在客户端上使用盐。这也暴露了你的算法,可以很容易地在客户端进行黑客攻击。最好的办法是通过 SSL (HTTPS) 执行此操作,以便对整个事务进行加密,并且身份验证仅在服务器上进行。
即:您的用户 ID 和密码是从客户端加密传输的。 Web 服务器解密数据并将其传递到服务器端身份验证功能,您可以在其中查找用户和关联的盐,执行密码 + 盐 + 哈希,并将其与存储的哈希进行比较以进行匹配。这意味着哈希值和盐根本不需要从服务器传输。
Hashing the password on the client would require the use of the salt on the client. This also exposes your algorithm for very easy hacking on the client side. The best thing to do is to perform this action over SSL (HTTPS) so that the entire transaction is encrypted and the authentication only happens on the server.
I.e.: Your user ID and password are transmitted encrypted from the client. The web server decrypts the data and passes it to your server-side authentication function where you look up the user and associated salt, perform password + salt + hash and compare it to the stored hash for a match. This means that the hash and then salt never need to be transmitted from the server at all.
您确实需要在传输密码的任何页面上使用 SSL。如果你尝试在客户端加密它们,它将采用 JavaScript,并且很容易进行逆向工程。
You really need to be using SSL on any page where you are transmitting passwords. If you try to encrypt them on the client side it will be in javascript and very easily reverse-engineerable.