In this post we'll discuss, how to use hashing technique to secure password.
As I explained in my last post, Hashing is also known as a one way hash OR Message Digest. Hashing is the one way process which generate fixed length representation of the supplied content, if content is changed the hash will be changed. As it is one way process, hash can be generated from the content but the original content cannot be retrieved back from the hash.
1. How to generate hash using Java?
With the use of MessageDigest class from java.security package, hash can be generated. Please refer the following sample code.
MessageDigest md = MessageDigest.getInstance("SHA1");
md.update(password.getBytes());
byte[] passHash = md.digest();
Now let’s understand the above sample code in detail
MessageDigest md = MessageDigest.getInstance("SHA1");
Is to create instance of the MessageDigest, by using static getInstance() function.
The supplied value ‘SHA1’ is the algorithm using which the MessageDigest will generate hash. The other algorithms are MD5, SHA-256 etc, which can be used instead of ‘SHA1’
md.update(password.getBytes());
The update function of the MessageDigest, is used to feed the content as byte array, on which hash to be generated. Here we have content in string form which is converted to byte array and supplied to the update function.
byte[] passHash = md.digest();
After adding content to the MessageDigest using update function, Hash can be generate by calling digest() function. It returns a hash in form of byte array.
2. As hash is generated as byte array, do I need to modify my database to store hash instead of password?
There is no need to modify database structure at all, generally password is being stored into the database as string (varchar or char datatype). We may convert the hash generated as a byte array to the string by using base64 encoding
Please refer following sample code.
String password = "secret_word";
MessageDigest md = MessageDigest.getInstance("SHA1");
md.update(password.getBytes());
byte[] passHash = md.digest();
String passHashStr = new BASE64Encoder().encode(passHash);
//passHashStr to store in to the database.
The Hash converted to String can be stored in to the database without changing existing database table structure.
3. If it is one way hash, how will I get original password back to compare with password supplied by user while login?
You don’t need to retrieve original password, it’s not even possible. Using same algorithm Hash can be generated on the password entered by user. And the hash can be used to compare with hash retrieved from database.
//Login information supplied by user
String userName = request.getParameter("UserName");
String password = request.getParameter("Password");
//Generate hash on password supplied by user.
MessageDigest md = MessageDigest.getInstance("SHA1");
md.update(password.getBytes());
byte[] passHash = md.digest();
String passHashStr = new BASE64Encoder().encode(passHash);
//Retrieve password hash stored from database
String passHashFromDB = getPasswordFromDatabase(userName);
//Compare password hash from DB to hash generated on password entered by user.
if(passHashStr.equals(passHashFromDB))
{
//Login successfull.
goToHomePage();
}
else
{
//Login failed
goToErrorPage();
}