If you are a programmer, you may have developed applications that store users or your customers’ information in database. How to store users’ or customers’ sensitive data (especially password) might be an issues for most programmer. How do you ensure and convience that your users or customers’ password are actually secured?
How will you keep the passwords secure and avoid exposing them? How secure is actually secure? I think, when a password is stored in database, the password is considered secure when:
- The password MUST NOT readable by anyone (the database administrators, system users and even hackers). Anyone can’t read the actual password even they have the right to login into the database. Therefore the password must be “encrypted”.
- The password MUST be unrecoverable by the application itself or the application developer. Therefore the password must be “encrypted” using one way encyption.
Programmer MUST NOT store passwords as plain text in database. This is totally not secure. If you found an website or application that able to recover your password by telling your password in phone or sending your password to your email, you can guess, by 99%, the application store your password in plain text form. Don’t use the application, the application’s database administrator ABLE to READ YOUR PASSWORD!
Programmer can store their passwords in a encrypted form. But remember, as long as you have the encrytion key, anyone can decrypt the password and get the original password.
Programmer SHOULD always store the hash values of the passwords (and NOT the password) in database. By using hash functions (such as MD5m SHA1) to calculate the hash value of the password, you will NOT to able to get back the original password unless you use brute-forcing method to test the passwords with the key to find the matching hash values. Storing only hash values of passwords in your database will ensure that an attacker’s job is made that MUCH more difficult. Depending on how “secure” you want the password to be, you can choose a better secure hashing function and larger keys to protect you password in your database.
There are a few problems you may encounter when calculating the hash values for password. If you are using MYSQL, MYSQL does have a built-in password() function that actually calculate the hash values of the password. However, the password function in not portable at all. When you want to change the DBMS (e.g. to DB2) or to upgrade MYSQL (e.g. from version 4 to version 5), the password data in database become useless. The password function is only supported by MYSQL DBMS and different version of MYSQL may generate different hash values for the same password. After all, the password validation becomes incorrect and all passwords must be regenereted. This is due to the behaviour of hash function where you can’t reverse the algorithm to get back to original password.
Storing an hash values for a password by simply calling the hash function without any key is inadequate. You can get same hash values for the same passwords. Therefore we will need to add in some extra information to make the hash values unique to a certain subject, that’s the cryptography keys.
At here I will show you a simple way to secure your password data in database. Before that let me define the specification and how secure I want my password to be:
- The hash values of passwords MUST be DBMS independent. e.g. I can change DBMS without any problem.
- The hash values of passwords MUST be application dependent. e.g. The same password values in different application should have different hash values, so that even there are same password values exist in different application, the database administrator MUST NOT be able to guess whether the password values are same by simply looking at the hash values.
- The hash values of passwords MUST be user/customer dependent. e.g. Eventhough there may have two same password values from different customer logins, the database administrator MUST NOT be able to guess whether the password values are same by simply looking at the hash value.
To accomodate the above requirements, I will need to define a key that is application dependant and another key that is user/customer dependent.
- Application key – you can choose anything that is unique to the application. e.g. The application name and code or the combination.
- User/Customer key – you can choose anything that is unique to the user/customer’s login. e.g. username, email and registration time or the combination.
Below is the code to calculate the hash value of a password:
define ('APPLICATION_KEY', 'Super Email Application - AHBKQBMSLIY'); function hash_password($username, $password, $time) { return sha1($username.'-'.$password.'-'.$time.'-'. APPLICATION_KEY); }
Simple right? The above function uses APPLICATION_KEY as the application key and the combination of username and registration time as the user/customer key. The above function also uses secure hash algorithm, SHA1 to calculate the hash function.
The returned value is always a 40-character hexadecimal number. To get the hash values to be stored in database, simply call the function by passing in username, password and registration time. To validate whether user/customer has keyed in the correct password, retrieve the hash value, registration time and password, then recalculate a new hash value together with the keyed in password and compare the new hash value with the hash value from database.
The above code is just a sample, you can develop your own one using different keys, different ways of calling the secure hash function and you may also want to use better hash function to calculate the hash values for passwords.
Leave a Reply