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

net.krotscheck.kangaroo.authz.common.util.PasswordUtil Maven / Gradle / Ivy

/*
 * Copyright (c) 2017 Michael Krotscheck
 *
 * 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.
 *
 */

package net.krotscheck.kangaroo.authz.common.util;


import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.crypto.digests.SHA3Digest;
import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.prng.DigestRandomGenerator;

import static org.bouncycastle.crypto.PBEParametersGenerator.PKCS5PasswordToBytes;

/**
 * Password hashing and comparison utilities.
 *
 * @author Michael Krotscheck
 */
public final class PasswordUtil {

    /**
     * Random generator.
     */
    private static final DigestRandomGenerator GENERATOR =
            new DigestRandomGenerator(new SHA3Digest(512));

    /**
     * Private constructor for a utility class.
     */
    private PasswordUtil() {

    }

    /**
     * Create a new salt using Java's SecureRandom for good entropy.
     *
     * @return A 32-byte-sized salt.
     */
    public static String createSalt() {
        byte[] salt = new byte[32];
        GENERATOR.nextBytes(salt);
        return Base64.encodeBase64String(salt);
    }

    /**
     * Hash a password.
     *
     * @param password The password.
     * @param salt     The salt.
     * @return The hash.
     */
    public static String hash(final String password, final String salt) {
        Integer keyLength = 512;
        Integer iterations = 101501;
        byte[] saltBytes = Base64.decodeBase64(salt);
        byte[] passBytes = PKCS5PasswordToBytes(password.toCharArray());

        PKCS5S2ParametersGenerator generator = new PKCS5S2ParametersGenerator();
        generator.init(passBytes, saltBytes, iterations);

        KeyParameter keys = (KeyParameter)
                generator.generateDerivedParameters(keyLength);

        byte[] encodedPassword = keys.getKey();
        return Base64.encodeBase64String(encodedPassword);
    }

    /**
     * Test whether a password/salt combination match a hash.
     *
     * @param password The password.
     * @param salt     The salt.
     * @param hashed   The hash to compare them against.
     * @return True if they match, otherwise false.
     */
    public static Boolean isValid(final String password,
                                  final String salt,
                                  final String hashed) {
        return hash(password, salt).equals(hashed);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy