views:

766

answers:

9

The very basic issue all developers face: Whenever user submits the form, the password is sent via network and it must be protected. The site I develop for doesn't have HTTPS. Neither does the owner want to buy a SSL certificate, nor is he interested in a self-signed one. So I want to protect the password sent via HTTP using Javascript when submitting form.

To eager downvoters: http://stackoverflow.com/questions/1582894/how-to-send-password-securely-over-http DOES NOT give any sensible solution and I am in another situation.

If I use MD5, one can reverse that password string. What about nonce/HMAC? Any available Javascript library for that? Or do you have any suggestion/hint to tackle? Thanks in advance!

+2  A: 

Unfortunately there will be no way to ensure security of a non-encrypted request. Anyone with access to your javascript will simply be able to reverse engineer it/tamper with it and anyone with a packet sniffer will be able to watch the unencrypted traffic. These two facts together mean:

No SSL? No security.

thenduks
I would also argue that SSL is as bad as no security as you can purchase a CA signed certificate for a domain that you don't own. Albeit it is becoming more rare, but I'm sure I can find a CA that will take my money and sign a certificate. With that - how do you know the chase.com you go to is actually chase's site and not an attackers? They both can have valid signed certificates.
Nathan Adams
The big ones wont do this and lots of the others are poorly supported in the browsers. The situation isn't perfect but I wouldn't call it 'as bad' as no security.
thenduks
+1  A: 

Any transmission that you have will be in the clear; that is, without SSL your critical information will be exposed. It is worth discussing that point with the site Owner. In other words, it's best to take necessary measure to fortify your data transmission, and SSL is one the basic, cheap steps you can take.

David Robbins
+1  A: 

i don't think the issue here is the technology, but how you explain the importance of SSL. Provide them with reliable reading materials, i'm sure there are plenty over the web.

Martin Ongtangco
+3  A: 

If you REALLY want to deep-dive into this, look at the Diffie-Hellman key exchange which was created to "allow two parties that have no prior knowledge of each other to jointly establish a shared secret key over an insecure communications channel"

I'm not a cryptography expert though, so I don't fully know if it's really secure if an attacker has both the Client (JavaScript source code) and the transport mechanism (Packet sniffer)

Michael Stum
It's secure if you do it right... but doing it right is extremely hard. SSL is way, way less work.
Andrew McGregor
+15  A: 

There is no way to send a password securely that the user can verify without SSL.

Sure, you can write some JavaScript that will make a password secure for over-the-wire transmission through hashing or public-key-encryption. But how can the user be sure that the JavaScript itself has not been tampered with by a man-in-the-middle before it reached them, to send the password to an attacker instead of the site, or even just compromise the security of the algorithm? The only way would be for them to be expert programmers and have them inspect every line of your page and script to ensure it was kosher before typing the password. That is not a realistic scenario.

If you want passwords to be safe from man-in-the-middle attacks, you must buy an SSL cert. There is no other way. Get used to it.

If I use MD5, one can reverse that password string.

No... not trivially at least. Whilst MD5 has attacks against it, it's a hashing algorithm and thus unreversable. You would have to brute-force it.

But again, a man-in-the-middle attacker doesn't need to look at your MD5s. He can simply sabotage the JavaScript you send the user to make the MD5s.

bobince
+1 thanks for your explanation.
Viet
Excellent post. I tried to make a secure password input with JavaScript, and realized it wasn't possible for these exact reasons. I wish I could have read this first.
ojrac
<<Whilst MD5 has attacks against it, it's a hashing algorithm and thus unreversable. You would have to brute-force it.>> You're forgetting that there are pre-calculated tables of MD5'd password hashes, which means that "Brute forcing" could well be fast and trivial.
EricLaw -MSFT-
EricLaw: You're referring to Rainbow tables? They only contain hashes of text up to a certain length.
Noon Silk
Anyway, before choosing a hashing function, everyone should check the latest details of the one they decide on: http://valerieaurora.org/hash.html, specifically, MD5, SHA0, SHA1, are all considered dead. Use only SHA-2 and up.
Noon Silk
"If you want passwords to be safe from man-in-the-middle attacks, you must buy an SSL cert. There is no other way."Nonsense. You just add a challenge for a second round of hashing.See http://groups.google.com/group/comp.lang.php/browse_thread/thread/c5960aa0afac2621/ffd98ae87112ccc5C.
symcbean
As Jerry Stuckle says in that thread, it's still of no use. Adding more security on top makes no difference; the user would still have to read and verify that the client-side script sent to them was kosher before starting to type their credentials. That isn't going to happen. You need a secret of some sort to bootstrap a secure connection; SSL provides that in the form of shared CAs. Without it, you could be talking to any random active-MitM hacker pretending to be the target website. Password-hashing login schemes, although potentially useful for other reasons, can only defeat passive MitM.
bobince
+1 Thanks for further explanation :)
Viet
+1  A: 

The solution requires the client to be able to encrypt the password using a secret encryption key known only to the client and the server.

SSL accomplishes this by requiring both the server and the client web browser to have their own asymmetric public/private keypair, which they use to encrypt and transmit a random session key between them. The rest of the conversation then uses that secure session key.

So you're asking how to solve the same problem as SSL without the benefit of having a secret key that is known only to the client and server. I'm no expert, but it looks like this can't be done, or at least not easily.

Loadmaster
+3  A: 

You can use a javascript RSA implementation to encrypt the password before sending. (Here is an example of RSA In Javascript.)

But I believe both this one and using a hash function will be vulnerable to replay attacks. So, be careful.

Szere Dyeri
Shameless plug: I took that idea to the next level http://rsacpp.org/
Nathan Adams
A: 

If you don't have access to SSL, MD5 should be adequate to prevent accidental discovery of passwords (such as in a network log file or something). Anything else would be a waste of time. Just make sure the app doesn't give access to sensitive information (ie, credit card numbers, medical history, etc).

Like others commenters have suggested, a serious attacker will be able to break any type of security on the page. Even SSL is a small barrier since most users use easy-to-guess passwords, re-use the same passwords everywhere, will give their password to anybody that asks, or can be tricked into giving up their password by a copied page or "tech support" phone call.

Brian
+4  A: 

The solution here is to not send the password at all. Use challenge/response.

In the original form include a large block of random text along with a key. Store the original random text in the session based on key on the server. When the client submits the form, use JS to hash the random text and password together. Then send the username, key, and hashed random text to the server. DO NOT send the password. On the server, use the key to lookup the original random text, perform the same hashing operation with the stored password. If the server-hashed value matches the client hashed value, then you know the client entered the right password without ever sending the password to the server.

Sam
Viet