All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.rathravane.till.data.OneWayHasher Maven / Gradle / Ivy

There is a newer version: 2.1.1
Show newest version
package com.rathravane.till.data;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;

import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;

/**
 * A collection of utility functions for one-way hashing.
 * @author peter
 *
 */
public class OneWayHasher
{
	/**
	 * Create a digest of a message string.
	 * @param input
	 * @return a digest string.
	 */
	public static String digest ( String input )
	{
		return pbkdf2HashToString ( input, "(non-empty salt)" );
	}

	/**
	 * Create a hash of an input string and a salt string.
	 * @param input
	 * @param salt
	 * @return a hash
	 */
	public static String hash ( String input, String salt )
	{
		return pbkdf2HashToString ( input, salt );
	}

	/**
	 * Create a hash using pbkd2Hash and return the result as a string of hex characters.
	 * @param input
	 * @param salt
	 * @return a string of hex characters.
	 */
	public static String pbkdf2HashToString ( String input, String salt )
	{
		final byte[] bytes = pbkdf2Hash ( input, salt );
		return rrConvertor.bytesToHexString ( bytes );
	}

	/**
	 * Create a hash using the PBKDF2WithHmacSHA1 algorithm given an input string and salt string.
	 * @param input
	 * @param salt
	 * @return a hash in a byte array
	 */
	public static byte[] pbkdf2Hash ( String input, String salt )
	{
		try
		{
			final String algorithm = "PBKDF2WithHmacSHA1";
			final int derivedKeyLength = 160;
			final int iterations = 20000;

			final KeySpec spec = new PBEKeySpec ( input.toCharArray (), salt.getBytes (), iterations, derivedKeyLength );
			final SecretKeyFactory f = SecretKeyFactory.getInstance ( algorithm );
			return f.generateSecret ( spec ).getEncoded ();
		}
		catch ( NoSuchAlgorithmException e )
		{
			throw new RuntimeException ( e );
		}
		catch ( InvalidKeySpecException e )
		{
			throw new RuntimeException ( e );
		}
	}

	/**
	 * Hash an input with an app-provided salt using the older hash technique. 
	 * @param input
	 * @param moreSalt
	 * @return a hash string
	 * @deprecated Provided for older systems which may have stored the output as a password encoding.
	 */
	@Deprecated
	public static String oldHash ( String input, String moreSalt )
	{
		final byte[] outBytes = oldHashToBytes ( input, moreSalt );
		return rrConvertor.bytesToHexString ( outBytes );
	}

	/**
	 * return a 20 byte (160 bit) hash of the input string, using a salt, if provided.
	 * @param input
	 * @param moreSalt
	 * @return 20 bytes
	 * @deprecated Provided for older systems which may have stored the output as a password encoding.
	 */
	@Deprecated
	public static byte[] oldHashToBytes ( String input, String moreSalt )
	{
		try
		{
			final StringBuffer fullMsg = new StringBuffer ();
			fullMsg.append ( kPart1 );
			fullMsg.append ( input );
			fullMsg.append ( kPart2 );
			if ( moreSalt != null )
			{
				fullMsg.append ( moreSalt );
			}

			final MessageDigest md = MessageDigest.getInstance ( "SHA-1" );
			md.reset ();
			md.update ( fullMsg.toString().getBytes () );
			return md.digest ();	// 160 bits
		}
		catch ( NoSuchAlgorithmException e )
		{
			throw new RuntimeException ( "MessageDigest can't find SHA-1 implementation." );
		}
	}

	/**
	 * Run this utility as a program.
	 * @param args
	 */
	static public void main ( String args[] )
	{
		if ( args.length != 1 && args.length != 2 )
		{
			System.err.println ( "usage: oneWayHasher  []" );
		}
		else if ( args.length == 1 )
		{
			System.out.println ( pbkdf2HashToString ( args[0], "" ) );
		}
		else if ( args.length == 2 )
		{
			System.out.println ( pbkdf2HashToString ( args[0], args[1] ) );
		}
	}

	static private final String kPart1 = "In the fields of Rathravane, yell '";
	static private final String kPart2 = "!!!', and you'll find a rock thrown by a giant. ";
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy