Protect Your Users Passwords without an Expensive SSL Certificate

Date Published: 04/03/2009 00:55

Personal information security, one of the hottest topics on the lips of web professionals across the globe. How do we stop people not only hacking our sites and causing us inconvenience, but also how do we stop people accessing our users' personal information? Right now there is one major answer to these questions, SSL (secure socket layer). Proven technology which has fueled a boom in online transactions, allowing people to buy anything from dressing gowns to airplanes. However, SSL certificates can be costly to smaller web masters. These millions of people who offer a free service to the world hoping that their advertising may at least pay their hosting. Here is a small scale solution which can provide these people with an extra layer of security.

WARNING (Please Read)

This is a SMALL SCALE solution not intended for the communication of private information. This type of security should NOT be used on e-commerce applications or anything which deals with personal information of any kind. This is suitable only for small sites with log in areas which if compromised will not cause the leakage of valuable data.

How Can I Secure my Users Without SSL?

A large number of user on the web accounts which are compromised are the result of package sniffing. People who set up their servers to monitor packets which pass by for potentially valuable information. When using SSL this is not an issue since the encryption makes the data illegible to the sniffer but when using an open connection someone can easily pick up on an unencrypted user name and password. The key to SSL is that the data is encrypted before transport and we need to do that as regularly as we can. As web developers on the only client side resource available is JavaScript, executing on the users machine. We can use this (when enabled) to encrypt our data for us before it is sent to the server. Ofcourse this will only work when JavaScript is enabled but it is better that it is sometimes present rather than not there at all.

How Can I Implement this JavaScript Encryption?

You could argue that there are many ways to do this and this is only one. JavaScript does not have the likes of MD5 built in which can be used in other technologies to one-way encrypt data. However, it is possible to access it in the form of an user defined function. The best one I found for this was here (http://pajhome.org.uk/crypt/md5/index.html) and weights in at just over 8KB which isn't huge, especially since you will only be needing it on log in pages. You could also minify it to reduce it further (see www.dev-explorer.com/articles/apache-optimisation). The MD5 hash is the basis of our password encryption here.

Once you have MD5 working on both server and client, you can use it to hash the password of your user when they submit the form just prior to it being posted in a HTTP request across the world. When your server receives this hashed password it can compare it to its records and authenticate it since you should be storing encrypted passwords anyway. Storing plain text passwords is EXTREMELY bad practice and should be avoided at all times. If someone were to hack your database your users would be in a whole lot of trouble and it would be all YOUR fault. People often use the same password on different sites so they could lose there account on more than just your website.

But How Do I Know if the Password has been Encrypted Client Side?

I see that there are two ways to do this. You can create a hidden input field in the DOM before submission, which when present in the post request can signify that JavaScript was enabled at the time of log in. There is also the alternative of limiting your users to passwords less than 32 characters (the length of an MD5 hash). This way you know if the password they submit is 32 characters long it has already been hashed.

Extra Server-side Security Pre-cautions

If a packet sniffer were to pick up on your newly hashed password and submit it themselves, they could easily bypass this new security making it pointless. To combat this I would recommend using time based hashing routines on the server to determine when the initial form was rendered, and timing that form out meaning it can not be submitted after a certain period of time. We can implement this by client-side hashing the password once, and then hashing it with a value given by the server concatenated on the end a second time. This value can be worked out by an algorithm on the server based on the time and can change every 5-10 minutes. At the server you can look up the users screen name in the database and hash their (already hashed) password with values which would still be valid to see if you can attain a match. If so, let them in, if not, ask them to try again. The packet sniffers could see this time based value sent by the server but if its ambiguous enough they will not be able to work out how it is calculated on the server, meaning they will have to be pretty quick to hack in.

Conclusion

There it is, user authentication encryption without a costly SSL certificate. I will re-iterate that this is not a proven solution, not all people will be able to use it since they may not have JavaScript which renders it useless. You must still offer a non-JavaScript solution which works the traditional way to meet standards and to offer your site to as many people as possible. Always remember that your users deserve you to look at ideas like this to protect them since us, the developers, are the ones who have control of this data and its up to us to do the best we can with it.

Feel free to comment below if you have any ideas which could develop this further, or maybe you have tried it and have a story to tell. Please, no people saying how it is insecure and isn't a viable option. I've stated many times that its not the securest encryption method out there and that this is not suitable for use with private data but it is cheap, easy and works where possible, which is better than transmitting plain text.

Comments

Sorry comments are currently disabled for maintenence

5 Most Recent Articles

Manually Triggering Events in ASP.NET from JavaScript

A quick guide for ASP.NET developers on how to manually trigger ASP.NET events from JavaScript.

Advanced Use of MySQL Stored Procedures

An article for users of MySQL databases describing how they can use advanced stored procedures to improve efficiently in their applications.

Using MySQL Stored Procedures and Extending MySQLi in PHP

A guide for LAMP developers to using stored procedures in MySQL and extending the MySQLi class.

Reading and Writing to Excel Spreadsheets in Python

An introduction to using the xlwt and xlrd modules for python to interact with Microsoft Excel spreadsheets.

Interact with the Web Using Python and the HTTP Library

This is an introduction to making HTTP requests from a python script/application using httplib.

Sponsors