hash strings via javascript

Thursday 29th March 2007 01:11 PM

TAGS: javascript, hash
This is something possibly not thought of too often, and makes quite a lot of sense when you look into it more deeply. It's relatively easy to hash a string in almost any server side language, and most passwords are stored in this way.

MD5 and SHA1 are the two most commonly used hashs, in cryptography terms, this means there is no way to reverse engineer the string to find out the original value. It remains useful however, as you can "compare" the hashed value of something to hash you know (but don't know the value of) and see if they are the same.

Something a lot of you already know, so I won't rabbit on about it and get on to what I really want to discuss!

Now it's common for login boxes requiring passwords to be on unencrypted pages, this means when you submit a form containing your username/password, the raw values are sent from your computer to the server and any hash comparison calculated server side.



A packet sniffer could intercept the transmission at any stage from the data leaving your computer, across the local network and out across the internet before reaching the destination server and its network. Using some clientside javascript (MD5 and SHA1 javascript snippets) we can hash the password value directly in the browser before sending it.



It isn't a be all and end all of security measures as the hash itself could still be grabbed, but it is something to think about. Notably vBulletin use this method in their forum software.

Comments on this article:


#1 Jeroen Mulder says:

Thursday 29th March 2007 05:16 AM

Interesting idea, I never quite realised that. One problem that immediately comes to mind is the case with Javascript disabled.

I suppose a solution for this problem would be to add an extra field value to indicate whether the password is hashed or not, so the server-side script will know which process to initiate upon receiving the request?

#2 Gavin says:

Thursday 29th March 2007 06:08 AM

Yep, exactly - just have a hidden form field thats value is changed if javascript is present to alert the server what to do.

#3 Masklinn says:

Thursday 29th March 2007 06:10 AM

> Using some clientside javascript (MD5 and SHA1 javascript snippets) we can hash the password value directly in the browser before sending it.

And forbid anyone with javascript disabled or using a platform that doesn't handle javascript of using your website for no good reason.

There's a standard way to encrypt passworded login, it's called HTTPS, why are you trying to reinvent the wheel in a nonstandard and mostly stupid way.

#4 Gavin says:

Thursday 29th March 2007 06:21 AM

Read the above comment, it's very easy to detect if javascript is available or not. This is meant to be another barrier, rather than a "solve everything" solution.

HTTPS slows down requests, and puts a load on the server if you have it on every page, otherwise we'd run every site https by default. ;) If you look around on almost all popular sites, including google, they have login forms like this on non-https pages for that reason.

#5 JJ says:

Thursday 29th March 2007 06:40 AM

How is knowing what hash to send more secure than knowing what plain text password to send?

F.ex. if I can fake a HTTP POST message with a plain text password because I sniffed it, what's stopping me from sending the hashed password if I sniffed that?

#6 Gavin says:

Thursday 29th March 2007 06:54 AM

It doesn't reveal the plaintext password, and as long as you are 'salting' your passwords, even if they try and look it up using something like a rainbow table.

Hypothetically you can also send the calculated hash joined with a unique value which only the server knows, much like how captchas work.

#7 J.P. Larocque says:

Friday 30th March 2007 02:09 AM

Right.

Specifically, the best thing to do is to store passwords as plaintext (or under reversible encryption) on the server side.

Each login form comes with a unique, unguessable value (e.g. 128-bit random number). The client-side Javascript hashes the concatenation of the password and the random number; the random number should be sent during the login operation as well. The server verifies the hash result with its own hash of the plaintext password and the random number, and then invalidates that random number for future use (e.g. by adding it to a set of seen random numbers) to prevent replay attacks.

Nevertheless, HTTPS is certainly more elegant and secure. If you've concluded that it imposes too high a CPU load on the server for all web pages, consider using it only for login, as eBay and other sites do.

#8 oh my says:

Thursday 12th April 2007 11:19 AM

I don't know where to start guys. I think I'll attack the random number thing since that's the most secure idea here.

What's to stop an attacker from sniffing a client supplied hash and random number, then performing a dictionary attack on the password with the supplied random number. Of course you can get creative in how you mingle the random number but then you're relying on the secret of the algorithm. Good cryptography exposes the algorithm and lets intractability do the rest.

Do not store passwords as plain text on the server, and sanitize your log files for %$^%*

You are wasting time. This problem is already solved with ssl. Solve something else.


Add Comment:


Make a Comment

*Nb, all comments are moderated to prevent spam or inappropriate content.








netforge logo
netforge provides high quality and friendly website design services to business. We're Australian based and reliable... (find out more).