Tuesday, May 16, 2006

Password Encryption & Security

I just wanted to give a plug to this article which provides a very good overview of some important aspects of software application security:

How Developers Can Help Protect Application Data

I've been reviewing various encryption and security mechanisms. Of interest is the debate between storing an MD5 Hash in the database versus encrypting passwords by some other means.

The basic gist of the discussion is that by using encryption you have to have a key and that key, if stolen, can be used by a hacker to figure out your passwords and login to your applications. Worse yet, people tend to use the same passwords across different systems on the Internet. A hacker could gain access to the email address and password and attempt to log in at banking sites and other critical systems to steal user information. For this reason I personally use separate passwords for different types of applications with different levels of critical data on the net.

A potentially safer mechanism would be to use an MD5 or SHA hash with random "salt" or "seed" to generate the digest. Then store the results which will be a meaningless piece of data in the database which can never be decrypted, but can be used for comparison when logging into a system to make sure the user name and password match. This would not work if the password ever needs to be retrieved for some reason, but in general it would probably be better to just reset the password if lost, rather than send it back to someone in an email which is highly insecure. Of note, I have read reports that MD5 can be subject to brute force attacks and SHA, in general seems to be a better choice per word on the street, however I also read a post that theoretically SHA has been cracked in a lab setting. Still, any encryption is better than none as it makes it one step harder to access the data.

Encrypting passwords in databases is only one piece of the puzzle however. Even if encrypted a hacker could obtain the encrypted version of the password or hash and log into the application which is using that particular encrypted or hashed password. Therefore it is also important to protect the data as it passes between the web browser and the server, as another at least basic means of securing the data. Using an SSL certificate and communicating via https instead of http when passing data back and forth between the browser and server ensures that someone cannot access the data in transit and use it to login. If they do that data will be encrypted so they will not be able to obtain the hashed value.

I have seen the argument that someone could build their own code somewhere and host it to login to a web application. In other words, your site has a page on it with a login form that, when submitted, calls code to generate a hash and compare the login against the hash in the database and login. Someone else, if they had the hash, could create a way to submit the straight hash to the database in theory and login even if they don't know the password. Well assuming you have protected your server(s) so the hacker cannot upload executable files you could put a mechanism of verifying the referrer to your login code is coming from the correct source. I have not looked into the possibility of altering the referrer in the header being passed in but at least it adds one more level of protection and I am sure there is a mechanism for further verifying this information.

One other security mechanism to consider is forcing users to create strong passwords and creating validation mechanisms both when entering new passwords and when logging in. Additionally in the case of a hacker trying to hit a login form with random values until they obtain a password you could put in some sort of verification that it is a real user such as forcing the person logging in to enter a series of random numbers or letters generated on the screen in a graphic (which cannot be screen scraped like html text and hard to parse by an automated mechanism).

Hopefully this will steer some software developers in the right direction when attempting to encrypt passwords and implement application security.