Java MD5 Hashing & Salting: Secure Your Passwords

Java MD5 Hashing & Salting: Secure Your Passwords

Friday, July 18, 2014

5:46 PM

The MD5 Message-Digest Algorithm is a widely used cryptographic hash function that produces a 128-bit (16-byte) hash value. MD5 has been employed in a wide variety of security applications, and is also commonly used to check data integrity. MD5 was designed by Ron Rivest in 1991 to replace an earlier hash function, MD4. An MD5 hash is typically expressed as a 32-digit hexadecimal number.

The Hash

A cryptographic hash function is a hash function, that is, an algorithm that takes an arbitrary block of data and returns a fixed-size bit string, the hash value, such that an change to the data will change the hash value. The data to be encoded is often called the “message,” and the hash value is sometimes called the message digest or simply digest.

Below is an example of generating MD5 Hash value for any input in Java usingjava.security.MessageDigest.

package net.viralpatel.java.md5;

import java.math.BigInteger;

import java.security.MessageDigest;

import java.security.NoSuchAlgorithmException;

public class JavaMD5Hash {

public static void main(String[] args) {

String password = “MyPassword123”;

System.out.println(“MD5 in hex: ” + md5(password));

System.out.println(“MD5 in hex: ” + md5(null));

//= d41d8cd98f00b204e9800998ecf8427e

System.out.println(“MD5 in hex: “

+ md5(“The quick brown fox jumps over the lazy dog”));

//= 9e107d9d372bb6826bd81d3542a419d6

}

public static String md5(String input) {

String md5 = null;

if(null == input) return null;

try {

//Create MessageDigest object for MD5

MessageDigest digest = MessageDigest.getInstance(“MD5”);

//Update input string in message digest

digest.update(input.getBytes(), 0, input.length());

//Converts message digest value in base 16 (hex)

md5 = new BigInteger(1, digest.digest()).toString(16);

} catch (NoSuchAlgorithmException e) {

e.printStackTrace();

}

return md5;

}

}

Above example is quite straight forward. The main() method calls md5() method to get MD5 hash value of any input. In md5() method we used java.security.MessageDigest class’s object to generate Md5 hash. Note how we used java.math.BigInteger to convert the message digest into hex values of base 16.

Alternately, you can also use Apache Commons Codec library to covert any string to Md5 hash. The commons-codec.jar contains class org.apache.commons.codec.digest.DigestUtils that can be used to generate MD5 hash. Following is the code snippet for same:

package net.viralpatel.java.md5;

import org.apache.commons.codec.digest.DigestUtils;

public class JavaMD5Hash {

public static void main(String[] args) {

String password = “MyPassword123”;

System.out.println( DigestUtils.md5Hex( password ) );

}

}

Thus if your project already uses commons-codec jar then it is advisable to use DigestUtils.md5Hex()method to generate MD5 hash values.

The Salt

The wikipedia definition of salt is:

In cryptography, a salt consists of random bits, creating one of the inputs to a one-way function. The other input is usually a password or passphrase. The output of the one-way function can be stored rather than the password, and still be used for authenticating users. The one-way function typically uses a cryptographic hash function.

Thus basically, salt is a random data string that one can append to the password before hashing it. Consider a scenario where in a system users passwords are stored in database table after hashing them. So the plain text password are hashed using hash algo like Md5 and than stored in database. Now it is possible to perform a dictionary attack based on hash values. A plain hash can be looked up in a lookup table and its corresponding password string can be retrieved.

So instead of directly hashing passwords, we append a random string to it before hashing.

String password = “mypassword”;

String salt = “Random$SaltValue#WithSpecialCharacters12@$@4&#%^$*”;

String hash = md5(password + salt);

Thus the benefit provided by using a salted password is making a lookup table assisted dictionary attack against the stored values impractical, provided the salt is large enough. That is, an attacker would not be able to create a precomputed lookup table of hashed values (password + salt), because it would take too much space. A simple dictionary attack is still very possible, although much slower since it cannot be precomputed.

It is generally advisable to have salt value large and random with lot of special characters. Also application wide single salt value must be used so that users can be authenticated irrespective of when accounts were created. The salt value must be stored outside application data and must be loaded with application.