Sunday, 16 November 2014

Generating MD5 hash in Java

Background

Heard of MD5 hashing algorithm ?  MD5 stands for Message Digest algorithm 5 which is a cryptographic algorithm invented by Ronald Rivest in 1991 for calculating hash values. So MD5 is a widely used hashing algorithm in many companies and firms. (MD5 Wiki)

How did I get here you ask ? 

I was trying to understand how passwords are stored in database. For example you create a website where users can login you will need to store user credentials - username and password for instance. Now how would you store the password ? Plain text ? Don't guess... answer is NO! It is a major security flaw. Anyone can get the passwords once they get into the file system you are using to store the passwords. Then store in encrypted ? Better idea then storing as raw text but again not recommended. Once someone knows the encryption method you have used all your sensitive data is gone. Infact developers developing the product should not know what passwords users have. And answer to all of it is hash the password string and store it which is exactly why we are looking at MD5 algorithm in this post. Well... natural question to follow is how is password verified when user logs in again? Again the hash of user entered password is generated and compared against the save hash value.

Infact you can use MD5 checksum to verify integrity of your files after transferring it over the network. In linux you can use md5sum command to calculate the checksum value. 

  • Hash is 128 bit or 16 byte or 32 hex characters.



If checksum is same after transferring your file over the network then your files is transferred correctly. If it's not the same that mean your file is corrupted.

To the Code

 Java code to generate MD5 hash is as follows - 

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;


public class MD5HashDemo {
    
    public static void main(String args[]) throws IOException 
    {
        
        String password = "password";
        try {
            System.out.println("MD5 hash generated : " + getMD5Hash(password));
        } catch (NoSuchAlgorithmException e) {
            System.out.println("Could not generate MD5 hash for password");
            e.printStackTrace();
        }
        
    }
    
    public static String getMD5Hash(String password) throws NoSuchAlgorithmException, UnsupportedEncodingException
    {
        
        byte[] passwordBytes = password.getBytes("UTF-8");
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] md5Bytes = md.digest(passwordBytes);
        
        StringBuffer hexStringBuffer = new StringBuffer();
        for (int i=0;i<md5Bytes.length;i++) {
            String hexString=Integer.toHexString(md5Bytes[i] & 0xff);
                if(hexString.length()==1) 
                {
                hexStringBuffer.append('0');
                }
            hexStringBuffer.append(hexString);
        }
        
        return hexStringBuffer.toString();
    }

}


Output : 
MD5 hash generated : 5f4dcc3b5aa765d61d8327deb882cf99

Above is just plain raw method to generate MD5 hash but we need not code from scratch. We have libraries that help us do that. You can use commons-codec library which apache provides. Then you can get the hash by simply executing -

org.apache.commons.codec.digest.DigestUtils.md5Hex(password);

Even Spring framework provides such a method.

Note :  See how I have used "UTF-8" encoding in getBytes() method? It is a good idea to do so unless you are using a specific encoding throughout your application. If not provided system encoding is picked up by default which may vary from system to system.


Lets now come to million dollar question....

Is it possible to decrypt md5 hashes?

Answer is No! If we could then why bother for hashing we could go for good encryption only. So we cannot get the original string from the hash unless you use Rainbow tables do some kind of brute forcing technique to guess.  But even using that it is almost impossible to get the original string back.

Also if you use Salt to generate the hash then even above techniques won't work. Using salt gives different hashes every time for same String input. But note using salt will not work in case of passwords for obvious reasons (you will not be able to compare it then)



Related Links

No comments:

Post a Comment

t> UA-39527780-1 back to top