Password hashing (non-SSL)

2019-04-05 10:01发布

问题:

How is the password sent from browser to server in case of non-ssl transfer?

I want to use bcrypt to hash password+salt before sending.... but it seems there is no javascript implementation for the bcrypt algorithm...

is md5, SHA-1 good enough?

PS: My site does not store any user personal information.. I just want that user intended password is not hacked as user might be using the same password at other sites that contains his/her personal information

回答1:

Truthfully, you can hash it on the front end, but it isn't going to solve your underlying problem. Since you are going to store the hash for later verification, all a hacker needs to know is what the hashed value is. Then the hacker can send the hashed value to you, and you're system will authenticate it as the correct value. You are essentially sending the password unencrypted to the system.

To be effective at all, the transfer needs to be encrypted through SSL.

Actually, the easy way to get around the hashing issue is to just play the man in the middle attack. Since it's not using SSL, the person using the browser has no way of knowing the HTML content is not from your server. An attacker can simply position his code in between the client and the server and place additional code in the HTML to key log the password. The posted information then goes to the attacker; he or she takes what is wanted (in this case the password), and then forwards the information along to your server. Neither you nor the attacker will know you are not communicating to each other.

This the reason why you have to buy a certificate from a verifiable source. They are verifying that the server you are communicating with is who they say they are.

Related: Poisoning the DNS



回答2:

Your method seems very insecure. But to approach your questions...

  1. The same way it would be sent over SSL, just unencrypted.
  2. No, MD5 is not good enough, even over SSL. If you are truly worried about security, then why would you choose a cracked algorithm that can be deciphered using a multitude of web services online (this has been the focus of a few sprited debates here on SO).
  3. Even if you hash the passwords before sending them, you are doing this CLIENT SIDE. This means that your hash and your algorithm are exposed and shown to every end user. As a result, a well to do hacker now knows exactly how you are sending the passwords.

In closing, just get at least a $20 SSL cert from GoDaddy if you want to secure your site/text during transfer from client to server. Encrypt your passwords on the server side before storing to your DB.



回答3:

Maybe you can try to implement the APOP command http://www.ietf.org/rfc/rfc1939.txt



回答4:

Depending on what you are doing, you might be able to offload your authentication to openid.



回答5:

I always recommend people use SSL where they can, but for completeness, it should be noted that it is possible to perform authentication securely without SSL through careful implementation of HMAC -- Hash-Based Message Authentication Code.

You must be sure to use a cryptographically secure hash algorithm with HMAC (I'd suggest SHA-224 or better), and you must remember that although you can authenticate without revealing the key/password this way, your data still has to be transmitted in cleartext, so this can't be used as a substitute to SSL for things like credit card transactions etc.



回答6:

Hmmm,

Challenge response protocol would work here.

Client fetches login page
1) Start session
2) Generate session key
3) Send session key as hash target
User logs in, presses submit
1) Javascript Task SHA-1 of session key + SHA-1 of password, writes result to password field
2) Javascript subimts form
3) Server takes SHA-1 of session key + SHA-1 password hash and compares

The session key is what keeps an eavesdropper from replaying the stream. The server remembers what it was.

HOWEVER, SHA1 of password should use salt. Simply using the username might be good enough to prevent a prebuilt rainbow table from working. Since the salt will be exposed in this protocol you can't completely defeat rainbow tables.

EDIT: In retrospect I didn't make one thing clear. The session id I'm talking about is not the PHP session id. It is an extra id stored in a session variable and passed to the client in the form. It needs to be used once for authentication and discarded from the PHP session variable afterwords. All the same, a sniffer can hijack the session after that point.

Please bear in mind that all this question asked for is a way to protect the password from sniffers. His own site is completely vulnerable to anybody who can sniff and hijack a session and he knows this.

BIG FAT WARNING: a MITM attacker can replace the javascript code with something that does something else like provide him a copy of the password. Only SSL can protect against this attack.