使用 PBKDF2 导出密钥

使用 PBKDF2 导出密钥

java默认提供的方法为:

    /**
     * 使用算法 PBKDF2 基于 SHA-256 导出密钥
     * 使用 JCE 默认方法,使用默认的 Provider
     *
     * @param password       口令
     * @param salt           盐值
     * @param iterationCount 迭代次数
     * @return 导出结果
     */
    public static byte[] derivedKeyUsingJCE(char[] password, byte[] salt, int iterationCount) throws GeneralSecurityException {
        SecretKeyFactory fact = SecretKeyFactory.getInstance("PBKDF2WITHHMACSHA256");
        return fact.generateSecret(new PBEKeySpec(password, salt, iterationCount, KEY_LENGTH)).getEncoded();
    }

参考代码:

import org.bouncycastle.crypto.PBEParametersGenerator;
import org.bouncycastle.crypto.digests.SHA256Digest;
import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Hex;

import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import java.security.GeneralSecurityException;
import java.security.Security;

/**
 * @author youngbear
 * @email [email protected]
 * @date 2020/6/30 22:40
 * @blog https://blog.csdn.net/next_second
 * @github https://github.com/YoungBear
 * @description 使用 PBKDF2 算法导出口令
 */
public class PBKDF2Practise {

    // key 长度 256 bit,32字节
    private static final int KEY_LENGTH = 256;
    // 测试盐值(随机生成)
    private static final byte[] TEST_SALT = {127, 28, 114, -2, -84, -125, -6, 27, 44, 109, 82, 127, 43, 124, 5, 99};
    // 测试口令
    private static final String TEST_PASSWORD = "@T2b45&l";
    // 测试迭代次数
    private static final int ITERATION_COUNT = 1000;

    public static void main(String[] args) throws GeneralSecurityException {
        char[] passwordChars = TEST_PASSWORD.toCharArray();
        byte[] bytesBC = derivedKeyUsingBC(passwordChars, TEST_SALT, ITERATION_COUNT);
        System.out.println(Hex.toHexString(bytesBC));
        byte[] bytesJCE = derivedKeyUsingJCE(passwordChars, TEST_SALT, ITERATION_COUNT);
        System.out.println(Hex.toHexString(bytesJCE));
        byte[] bytesJCEBC = derivedKeyUsingJCEBC(passwordChars, TEST_SALT, ITERATION_COUNT);
        System.out.println(Hex.toHexString(bytesJCEBC));

    }

    /**
     * 使用算法 PBKDF2 基于 SHA-256 导出密钥
     * 使用 BouncyCastle 提供的 low-level API
     *
     * @param password       口令
     * @param salt           盐值
     * @param iterationCount 迭代次数
     * @return 导出结果
     */
    public static byte[] derivedKeyUsingBC(char[] password, byte[] salt, int iterationCount) {
        PBEParametersGenerator generator = new PKCS5S2ParametersGenerator(new SHA256Digest());
        generator.init(PBEParametersGenerator.PKCS5PasswordToUTF8Bytes(password), salt, iterationCount);
        return ((KeyParameter) generator.generateDerivedParameters(KEY_LENGTH)).getKey();
    }

    /**
     * 使用算法 PBKDF2 基于 SHA-256 导出密钥
     * 使用 JCE 默认方法,使用默认的 Provider
     *
     * @param password       口令
     * @param salt           盐值
     * @param iterationCount 迭代次数
     * @return 导出结果
     */
    public static byte[] derivedKeyUsingJCE(char[] password, byte[] salt, int iterationCount) throws GeneralSecurityException {
        SecretKeyFactory fact = SecretKeyFactory.getInstance("PBKDF2WITHHMACSHA256");
        return fact.generateSecret(new PBEKeySpec(password, salt, iterationCount, KEY_LENGTH)).getEncoded();
    }

    /**
     * 使用算法 PBKDF2 基于 SHA-256 导出密钥
     * 使用 JCE 默认方法,使用 BouncyCastle 的 Provider
     *
     * @param password       口令
     * @param salt           盐值
     * @param iterationCount 迭代次数
     * @return 导出结果
     */
    public static byte[] derivedKeyUsingJCEBC(char[] password, byte[] salt, int iterationCount) throws GeneralSecurityException {
        Security.addProvider(new BouncyCastleProvider());
        SecretKeyFactory fact = SecretKeyFactory.getInstance(
                "PBKDF2WITHHMACSHA256", "BC");
        return fact.generateSecret(new PBEKeySpec(password, salt, iterationCount, KEY_LENGTH)).getEncoded();
    }
}

其中,使用BouncyCastle的话,需要引入pom依赖:

<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk15on</artifactId>
    <version>1.65</version>
</dependency>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章