package com.cloudhopper.commons.util; /* * #%L * ch-commons-util * %% * Copyright (C) 2012 Cloudhopper by Twitter * %% * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * #L% */ // java imports import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; // my imports import com.cloudhopper.commons.util.codec.Base64Codec; /** * Utility class to hash strings (such as passwords). * <br> * <ul> * <li>MD5 - hash is always 16 bytes, 32 char hex string, 24 char base-64 * <li>SHA1 - hash is always 20 bytes, 40 char hex string, 28 char base-64 * <li>SHA256 - hash is always 32 bytes, 64 char hex string, 44 char base-64 * <li>SHA512 - hash is always 64 bytes, 128 char hex string, 88 char base-64 * </ul> * <br> * NOTE: These are only 1-way hashes, you won't be able to decrypt the string. * * @author joelauer (twitter: @jjlauer or <a href="http://twitter.com/jjlauer" target=window>http://twitter.com/jjlauer</a>) */ public class Hasher { private static final String ALGORITHM_MD5 = "MD5"; // Message Digest Algorithm - 128 bit private static final String ALGORITHM_SHA1 = "SHA-1"; // Secure Hash Algorithm - 160 bit private static final String ALGORITHM_SHA256 = "SHA-256"; // 256 bit private static final String ALGORITHM_SHA512 = "SHA-512"; // 512 bit /** * Enum that represents each different algorithm supported by the Hasher. */ public enum Algorithm { /** Message Digest Algorithm - 128 bit */ MD5 (ALGORITHM_MD5), /** Secure Hash Algorithm - 160 bit */ SHA1 (ALGORITHM_SHA1), /** Secure Hash Algorithm - 256 bit */ SHA256 (ALGORITHM_SHA256), /** Secure Hash Algorithm - 512 bit */ SHA512 (ALGORITHM_SHA512); private final String algorithm; Algorithm(final String algorithm) { this.algorithm = algorithm; } @Override public String toString() { return this.algorithm; } } private Algorithm algorithm; public Hasher() { this.algorithm = Algorithm.MD5; } public Hasher(Algorithm algorithm) { this.algorithm = algorithm; } /** * Hashes the input String into a hex encoded hashed String. * <br> * <ul> * <li>MD5 - hash is always 32 char hex string * <li>SHA1 - hash is always 40 char hex string * <li>SHA256 - hash is always 64 char hex string * <li>SHA512 - hash is always 128 char hex string * </ul> * @param string0 The String to hash. This assumes its an ASCII string. * @return The hex encoded hashed String * @throws NoSuchAlgorithmException */ public String toHashedHexString(String string0) throws NoSuchAlgorithmException { return this.toHashedHexString(StringUtil.getAsciiBytes(string0)); } /** * Hashes the input bytes into a hex encoded hashed String. * <ul> * <li>MD5 - hash is always 32 char hex string * <li>SHA1 - hash is always 40 char hex string * <li>SHA256 - hash is always 64 char hex string * <li>SHA512 - hash is always 128 char hex string * </ul> * @param bytes The bytes to hash * @return The hex encoded hashed String * @throws NoSuchAlgorithmException */ public String toHashedHexString(byte[] bytes) throws NoSuchAlgorithmException { return HexUtil.toHexString(toHashedBytes(bytes)); //return StringUtil.toHexString(toHashedBytes(bytes)); } /** * Hashes the input String into a Base-64 encoded hashed String. * <ul> * <li>MD5 - hash is always 24 char base-64 * <li>SHA1 - hash is always 28 char base-64 * <li>SHA256 - hash is always 44 char base-64 * <li>SHA512 - hash is always 88 char base-64 * </ul> * @param string0 The String to hash. This assumes its an ASCII string. * @return The Base-64 encoded hashed String * @throws NoSuchAlgorithmException */ public String toHashedBase64String(String string0) throws NoSuchAlgorithmException { return this.toHashedBase64String(StringUtil.getAsciiBytes(string0)); } /** * Hashes the input bytes into a Base-64 encoded hashed String. * <ul> * <li>MD5 - hash is always 24 char base-64 * <li>SHA1 - hash is always 28 char base-64 * <li>SHA256 - hash is always 44 char base-64 * <li>SHA512 - hash is always 88 char base-64 * </ul> * @param bytes The bytes to hash * @return The Base-64 encoded hashed String * @throws NoSuchAlgorithmException */ public String toHashedBase64String(byte[] bytes) throws NoSuchAlgorithmException { byte[] hashedBytes = toHashedBytes(bytes); return Base64Codec.encode(hashedBytes); //return StringUtil.getAsciiString(toHashedBase64Bytes(bytes)); } /** * Hashes the input bytes into a Base-64 encoded hashed byte[]. * <ul> * <li>MD5 - hash is always 24 bytes base-64 * <li>SHA1 - hash is always 28 bytes base-64 * <li>SHA256 - hash is always 44 bytes base-64 * <li>SHA512 - hash is always 88 bytes base-64 * </ul> * @param bytes The bytes to hash * @return The Base-64 encoded hashed byte[] * @throws NoSuchAlgorithmException */ //public byte[] toHashedBase64Bytes(byte[] bytes) throws NoSuchAlgorithmException { // return Base64.encodeBase64(toHashedBytes(bytes)); //} /** * Hashes the input bytes into a hashed byte[] -- no special encoding. * <ul> * <li>MD5 - hash is always 16 bytes * <li>SHA1 - hash is always 20 bytes * <li>SHA256 - hash is always 32 bytes * <li>SHA512 - hash is always 64 bytes * </ul> * @param bytes The bytes to hash * @return The hashed byte[] * @throws NoSuchAlgorithmException */ public byte[] toHashedBytes(byte[] bytes) throws NoSuchAlgorithmException { MessageDigest messageDigest = MessageDigest.getInstance(algorithm.toString()); return messageDigest.digest(bytes); } }