A not-that-unsecure login form
No Translations
This article discusses a way for HTML login forms not to transmit plain-text passwords over the internet when SSL or https are too complex and still in your TODO list. This is an enhancement of this solution.
Krg’s solution
The author of the original article proposes to use javascript to salt (with a timestamp) the password and calculate its MD5 before sending it over the web. The login form sends the MD5 and the timestamp to the server. The server then reads the password from the database, salts it with the timestamp sent by the browser, calculates the MD5, and compares it with the one sent by the browser. That’s it, the browser did not send your password in clear text through a non-secure socket.
No plain-text password
But still, this implies that your password is stored in plain-text in the database. Do never store plain passwords in a databases. If the database gets compromised, the attacker would be able to know the password for all users. Do you use different passwords for each and every website or application you use? I don’t. Nobody does. My credit card is the sole owner of a unique password. A malvolent attacker who knows your password can then read your emails, access your facebook personal data and so on. Cypher the passwords before storing them. MD5 them, at least. Salt them before, too. No attacker will be able to know a password from the MD5, salted digest. Maybe the attacker knows how you generate the stored version of the password, and will be able to change the password of a user, so he can log into the system, but then you will know it happened because the actual user won’t be able to log in and will complain.
Hash the hash
The solution is the following:
On the client side (say, a javascript in the browser):
- Hash the unsalted password
- Salt it
- Hash it again
- Send both the salt and the result to the server
On the server site (say, in your php):
- Read the hashed password from the database
- Salt it
- Hash it
- Compare the calculated and the received one
Quite trivial, yes ? That’s how you neither transmit nor store plain passwords.
Drawbacks
This is not the eighth marvel of the modern world. This is still much vulnerable. Knowing how you salt and hash the passwords before sending them, and having eavesdropped enough to know the login and hashed password of a user, an attacker can perform a bruteforce calculation to get the original password. He doesn’t even need to send thousands of requests to your server, he will know when he has the correct password without a single try on your server. But that’s still a bit of work for the potential attackers, and this solution will remove from the game at least the dumb and the lazy ones.
March 11th, 2008 at 12:53 pm
Yes, it’s quite a classic solution.
Another better solution is to use OpenId
March 20th, 2008 at 6:58 pm
But what if you want your login form to be available on-line (then OpenId is OK), and in a closed-circuit intranet for a company who does not want an internet connection for any good reason? Make two different login forms? That means higher costs in development, maintainand and packaging. The one described here will run as-is anywhere. But anyway, you’re right, the online version should support enhanced Id support!