diff options
author | Anton Tananaev <anton.tananaev@gmail.com> | 2015-07-01 11:47:14 +1200 |
---|---|---|
committer | Anton Tananaev <anton.tananaev@gmail.com> | 2015-07-01 11:47:14 +1200 |
commit | 200ef5bb3fd4f194c47518e0633d7e8bb6ab6d79 (patch) | |
tree | 75853ff83b9a97e37d8d940025a2559484be5040 /src/org/traccar/helper/PasswordHash.java | |
parent | c099628f0cd07ca6545773a69824b567a6610675 (diff) | |
download | trackermap-server-200ef5bb3fd4f194c47518e0633d7e8bb6ab6d79.tar.gz trackermap-server-200ef5bb3fd4f194c47518e0633d7e8bb6ab6d79.tar.bz2 trackermap-server-200ef5bb3fd4f194c47518e0633d7e8bb6ab6d79.zip |
Re-implement hashing class
Diffstat (limited to 'src/org/traccar/helper/PasswordHash.java')
-rw-r--r-- | src/org/traccar/helper/PasswordHash.java | 231 |
1 files changed, 0 insertions, 231 deletions
diff --git a/src/org/traccar/helper/PasswordHash.java b/src/org/traccar/helper/PasswordHash.java deleted file mode 100644 index 98ded0988..000000000 --- a/src/org/traccar/helper/PasswordHash.java +++ /dev/null @@ -1,231 +0,0 @@ -package org.traccar.helper; - -/* - * Password Hashing With PBKDF2 (http://crackstation.net/hashing-security.htm). - * Copyright (c) 2013, Taylor Hornby - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -import java.security.SecureRandom; - -import javax.crypto.spec.PBEKeySpec; -import javax.crypto.SecretKeyFactory; - -import java.math.BigInteger; -import java.security.NoSuchAlgorithmException; -import java.security.spec.InvalidKeySpecException; - -/* - * PBKDF2 salted password hashing. - * Author: havoc AT defuse.ca - * www: http://crackstation.net/hashing-security.htm - */ -public class PasswordHash { - public static final String PBKDF2_ALGORITHM = "PBKDF2WithHmacSHA1"; - - // The following constants may be changed without breaking existing hashes. - public static final int SALT_BYTE_SIZE = 24; - public static final int HASH_BYTE_SIZE = 24; - public static final int PBKDF2_ITERATIONS = 1000; - - public static final int ITERATION_INDEX = 0; - public static final int SALT_INDEX = 1; - public static final int PBKDF2_INDEX = 2; - - public static class HashingResult { - - public final Integer iterations; - public final String hash; - public final String salt; - - public HashingResult(Integer iterations, String hash, String salt) { - this.hash = hash; - this.salt = salt; - this.iterations = iterations; - } - } - - /** - * Returns a salted PBKDF2 hash of the password. - * - * @param password - * the password to hash - * @return a salted PBKDF2 hash of the password - */ - public static HashingResult createHash(String password) { - return createHash(password.toCharArray()); - } - - /** - * Returns a salted PBKDF2 hash of the password. - * - * @param password - * the password to hash - * @return a salted PBKDF2 hash of the password - */ - public static HashingResult createHash(char[] password) { - // Generate a random salt - SecureRandom random = new SecureRandom(); - byte[] salt = new byte[SALT_BYTE_SIZE]; - random.nextBytes(salt); - - // Hash the password - byte[] hash = pbkdf2(password, salt, PBKDF2_ITERATIONS, HASH_BYTE_SIZE); - - return new HashingResult(PBKDF2_ITERATIONS, toHex(hash), toHex(salt)); - } - - /** - * Validates a password using a hash. - * - * @param password - * the password to check - * @param correctHash - * the hash of the valid password - * @return true if the password is correct, false if not - */ - public static boolean validatePassword(String password, String correctHash) - throws NoSuchAlgorithmException, InvalidKeySpecException { - return validatePassword(password.toCharArray(), correctHash); - } - - /** - * Validates a password using a hash. - * - * @param password - * the password to check - * @param correctHash - * the hash of the valid password - * @return true if the password is correct, false if not - */ - public static boolean validatePassword(char[] password, String correctHash) - throws NoSuchAlgorithmException, InvalidKeySpecException { - // Decode the hash into its parameters - String[] params = correctHash.split(":"); - int iterations = Integer.parseInt(params[ITERATION_INDEX]); - return validatePassword(password, iterations, params[SALT_INDEX], params[PBKDF2_INDEX]); - } - - public static boolean validatePassword(char[] password, int iterations, - String saltHex, String hashHex) { - byte[] salt = fromHex(saltHex); - byte[] hash = fromHex(hashHex); - // Compute the hash of the provided password, using the same salt, - // iteration count, and hash length - byte[] testHash = pbkdf2(password, salt, iterations, hash.length); - // Compare the hashes in constant time. The password is correct if - // both hashes match. - return slowEquals(hash, testHash); - } - - - - - public static boolean slowEquals(String hash1, String hash2) { - return slowEquals(fromHex(hash1), fromHex(hash2)); - } - - /** - * Compares two byte arrays in length-constant time. This comparison method - * is used so that password hashes cannot be extracted from an on-line - * system using a timing attack and then attacked off-line. - * - * @param a - * the first byte array - * @param b - * the second byte array - * @return true if both byte arrays are the same, false if not - */ - private static boolean slowEquals(byte[] a, byte[] b) { - int diff = a.length ^ b.length; - for (int i = 0; i < a.length && i < b.length; i++) - diff |= a[i] ^ b[i]; - return diff == 0; - } - - /** - * Computes the PBKDF2 hash of a password. - * - * @param password - * the password to hash. - * @param salt - * the salt - * @param iterations - * the iteration count (slowness factor) - * @param bytes - * the length of the hash to compute in bytes - * @return the PBDKF2 hash of the password - */ - private static byte[] pbkdf2(char[] password, byte[] salt, int iterations, - int bytes) { - try { - PBEKeySpec spec = new PBEKeySpec(password, salt, iterations, - bytes * 8); - SecretKeyFactory skf = SecretKeyFactory - .getInstance(PBKDF2_ALGORITHM); - return skf.generateSecret(spec).getEncoded(); - } catch (NoSuchAlgorithmException e) { - throw new RuntimeException(e); - } catch (InvalidKeySpecException e) { - throw new RuntimeException(e); - } - } - - /** - * Converts a string of hexadecimal characters into a byte array. - * - * @param hex - * the hex string - * @return the hex string decoded into a byte array - */ - private static byte[] fromHex(String hex) { - byte[] binary = new byte[hex.length() / 2]; - for (int i = 0; i < binary.length; i++) { - binary[i] = (byte) Integer.parseInt( - hex.substring(2 * i, 2 * i + 2), 16); - } - return binary; - } - - /** - * Converts a byte array into a hexadecimal string. - * - * @param array - * the byte array to convert - * @return a length*2 character string encoding the byte array - */ - private static String toHex(byte[] array) { - BigInteger bi = new BigInteger(1, array); - String hex = bi.toString(16); - int paddingLength = (array.length * 2) - hex.length(); - if (paddingLength > 0) - return String.format("%0" + paddingLength + "d", 0) + hex; - else - return hex; - } - - - -}
\ No newline at end of file |