Snippet: Creating secure Password Hashes in Java with Heimdall

July 12th, 2015 by

These days where a cheap GPU for about 100 € is capable to create 3 billion of MD5 Hashes per second, we need not only need to use salts the right way but we also need to choose a strong, non-reversible and slow hashing schemes when storing passwords in our application.

Heimdall is a library that implements a secure and upgradable password hashing mechanism and uses at the time of writing this article PBKDF2 SHA-1 HMAC with 20000 iterations and a 192 bit (24 byte) salt per default.

In the following short examples I’d like to demonstrate how to create password hashes, how to verify passwords and how to check if a password hash needs to be recreated using a more secure algorithm.

Password hashing with Heimdall

Password hashing with Heimdall

 

Why Heimdall?

Heimdall acts as a wrapper not only to create and verify hashes but also to check if a hash is outdated and needs to be recreated using a more secure algorithm or a higher iteration count.

QAWare have written a nice article about “Secure password storage and authentication” that summarizes common mistakes when storing passwords for further reading here.

More detailed information about hashing in Java is offered by the Open Web Application Security Project here.

For a discussion about choosing the correct iteration count when using PKBDF2-SHA256 can be found on Stackexchange.com here.

Dependencies

We need two dependencies here, Heimdall and Guava (afaik Guava won’t be needed with the upcoming version of Heimdall).

So finally this is our build.gradle (using Gradle):

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'application'
 
mainClassName = "com.hascode.tutorial.HeimdallExamples"
 
sourceCompatibility = 1.8
version = '1.0.0'
jar {
    manifest {
        attributes 'Implementation-Title': 'hasCode.com Heimdall Encryption Tutorial', 'Implementation-Version': version
    }
}
 
repositories {
	mavenCentral()
    maven {
        url 'https://raw.githubusercontent.com/qaware/heimdall/master/repository/'
    }
}
 
dependencies {
    compile 'de.qaware:heimdall:1.2'
    compile 'com.google.guava:guava:18.0'
}

Hashing in Action

In the following application, we’re ..

  • creating a password hash
  • printing the hash to STDOUT
  • verifying the hash against the password
  • verifying the hash against a false password

In addition, inside the verification method, we’re checking if our password hash needs a rehash.

package com.hascode.tutorial;
 
import de.qaware.heimdall.Password;
import de.qaware.heimdall.PasswordException;
import de.qaware.heimdall.PasswordFactory;
import de.qaware.heimdall.SecureCharArray;
 
public class HeimdallExamples {
 
	public static void main(final String[] args) throws PasswordException {
		char[] plaintextPassword = "soosecret".toCharArray();
 
		String hashedPassword = hashPassword(plaintextPassword);
		System.out.println("the hashed password is: " + hashedPassword);
 
		System.out.println("verifying a wrong password succeeds: " + verifyPassword("wrongpassword".toCharArray(), hashedPassword));
		System.out.println("verifying the right password succeeds: " + verifyPassword("soosecret".toCharArray(), hashedPassword));
	}
 
	private static String hashPassword(final char[] plaintextPassword) throws PasswordException {
		Password password = PasswordFactory.create();
		try (SecureCharArray cleartextPassword = new SecureCharArray(plaintextPassword)) {
			return password.hash(cleartextPassword);
		}
	}
 
	private static boolean verifyPassword(final char[] plaintextPassword, final String hashedPassword) throws PasswordException {
		Password password = PasswordFactory.create();
 
		try (SecureCharArray cleartext = new SecureCharArray(plaintextPassword)) {
			if (password.verify(cleartext, hashedPassword)) {
				if (password.needsRehash(hashedPassword)) {
					String renewedHashedPassword = password.hash(cleartext);
					System.out.println("password needed rehash: new hash is " + renewedHashedPassword);
					// store new hash etc ...
				}
				return true;
			}
			return false;
		}
	}
}

We may run the application using our IDE our Gradle e.g.

$ gradle run
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:run
the hashed password is: 1:1:SKSJ8ayV9Lxo/J7wh2opqVeqJKc82Dic:i=4e20:MmsdqRcqN//ltOWfsw8FXoq0vhLI6hRb
verifying a wrong password succeeds: false
verifying the right password succeeds: true
 
BUILD SUCCESSFUL
 
Total time: 8.112 secs

Tutorial Sources

Please feel free to download the tutorial sources from my Bitbucket repository, fork it there or clone it using Git:

git clone https://bitbucket.org/hascode/heimdall-encryption-tutorial.git

Resources

Tags: , , , , , , , , ,

Search
Tags
Categories