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

io.polaris.core.crypto.CryptoKeys Maven / Gradle / Ivy

There is a newer version: 3.2.1
Show newest version
package io.polaris.core.crypto;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.annotation.Nonnull;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;

import io.polaris.core.collection.Iterables;
import io.polaris.core.consts.CharConsts;
import io.polaris.core.crypto.asymmetric.AsymmetricAlgorithm;
import io.polaris.core.crypto.symmetric.SymmetricAlgorithm;
import io.polaris.core.io.IO;
import io.polaris.core.random.Randoms;
import io.polaris.core.string.Strings;

/**
 * @author Qt
 * @since 1.8
 */
@SuppressWarnings("All")
public class CryptoKeys {

	public static final int DEFAULT_KEY_SIZE = 1024;
	public static final String SM2_DEFAULT_CURVE = "sm2p256v1";
	public static final String KEY_TYPE_JKS = "JKS";
	public static final String KEY_TYPE_PKCS12 = "pkcs12";
	public static final String CERT_TYPE_X509 = "X.509";

	static {
		ICryptoProviderLoader.loadProviders();
	}


	// region 获取密钥生成器或工厂

	/**
	 * @param algorithm 对称加密算法
	 * @return
	 * @throws NoSuchAlgorithmException
	 */
	public static KeyGenerator getKeyGenerator(String algorithm) {
		try {
			return KeyGenerator.getInstance(getMainAlgorithm(algorithm));
		} catch (NoSuchAlgorithmException e) {
			throw new CryptoRuntimeException(e);
		}
	}

	public static KeyGenerator getKeyGenerator(String algorithm, String provider) {
		try {
			return KeyGenerator.getInstance(getMainAlgorithm(algorithm), provider);
		} catch (NoSuchAlgorithmException | NoSuchProviderException e) {
			throw new CryptoRuntimeException(e);
		}
	}

	public static KeyGenerator getKeyGenerator(String algorithm, Provider provider) {
		try {
			return KeyGenerator.getInstance(getMainAlgorithm(algorithm), provider);
		} catch (NoSuchAlgorithmException e) {
			throw new CryptoRuntimeException(e);
		}
	}

	/**
	 * @param algorithm 非对称加密算法
	 * @return
	 * @throws NoSuchAlgorithmException
	 */
	public static KeyPairGenerator getKeyPairGenerator(String algorithm) {
		try {
			return KeyPairGenerator.getInstance(getMainAlgorithm(algorithm));
		} catch (NoSuchAlgorithmException e) {
			throw new CryptoRuntimeException(e);
		}
	}

	public static KeyPairGenerator getKeyPairGenerator(String algorithm, String provider) {
		try {
			return KeyPairGenerator.getInstance(getMainAlgorithm(algorithm), provider);
		} catch (NoSuchAlgorithmException | NoSuchProviderException e) {
			throw new CryptoRuntimeException(e);
		}
	}

	public static KeyPairGenerator getKeyPairGenerator(String algorithm, Provider provider) {
		try {
			return KeyPairGenerator.getInstance(getMainAlgorithm(algorithm), provider);
		} catch (NoSuchAlgorithmException e) {
			throw new CryptoRuntimeException(e);
		}
	}

	/**
	 * @param algorithm 对称加密算法
	 * @return
	 * @throws NoSuchAlgorithmException
	 */
	public static SecretKeyFactory getSecretKeyFactory(String algorithm) {
		try {
			return SecretKeyFactory.getInstance(getMainAlgorithm(algorithm));
		} catch (NoSuchAlgorithmException e) {
			throw new CryptoRuntimeException(e);
		}
	}

	public static SecretKeyFactory getSecretKeyFactory(String algorithm, String provider) {
		try {
			return SecretKeyFactory.getInstance(getMainAlgorithm(algorithm), provider);
		} catch (NoSuchAlgorithmException | NoSuchProviderException e) {
			throw new CryptoRuntimeException(e);
		}
	}

	public static SecretKeyFactory getSecretKeyFactory(String algorithm, Provider provider) {
		try {
			return SecretKeyFactory.getInstance(getMainAlgorithm(algorithm), provider);
		} catch (NoSuchAlgorithmException e) {
			throw new CryptoRuntimeException(e);
		}
	}

	/**
	 * @param algorithm 非对称加密算法
	 * @return
	 * @throws NoSuchAlgorithmException
	 */
	public static KeyFactory getKeyFactory(String algorithm) {
		try {
			return KeyFactory.getInstance(getMainAlgorithm(algorithm));
		} catch (NoSuchAlgorithmException e) {
			throw new CryptoRuntimeException(e);
		}
	}

	public static KeyFactory getKeyFactory(String algorithm, String provider) {
		try {
			return KeyFactory.getInstance(getMainAlgorithm(algorithm), provider);
		} catch (NoSuchAlgorithmException | NoSuchProviderException e) {
			throw new CryptoRuntimeException(e);
		}
	}

	public static KeyFactory getKeyFactory(String algorithm, Provider provider) {
		try {
			return KeyFactory.getInstance(getMainAlgorithm(algorithm), provider);
		} catch (NoSuchAlgorithmException e) {
			throw new CryptoRuntimeException(e);
		}
	}


	public static Signature getSignature(String algorithm) {
		try {
			return Signature.getInstance(algorithm);
		} catch (NoSuchAlgorithmException e) {
			throw new CryptoRuntimeException(e);
		}
	}

	public static Signature getSignature(String algorithm, String provider) {
		try {
			return Signature.getInstance(getMainAlgorithm(algorithm), provider);
		} catch (NoSuchAlgorithmException | NoSuchProviderException e) {
			throw new CryptoRuntimeException(e);
		}
	}

	public static Signature getSignature(String algorithm, Provider provider) {
		try {
			return Signature.getInstance(getMainAlgorithm(algorithm), provider);
		} catch (NoSuchAlgorithmException e) {
			throw new CryptoRuntimeException(e);
		}
	}

	public static Cipher getCipher(String algorithm) {
		try {
			return Cipher.getInstance(algorithm);
		} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
			throw new CryptoRuntimeException(e);
		}
	}

	public static Cipher getCipher(String algorithm, String provider) {
		try {
			return Cipher.getInstance(getMainAlgorithm(algorithm), provider);
		} catch (NoSuchAlgorithmException | NoSuchProviderException | NoSuchPaddingException e) {
			throw new CryptoRuntimeException(e);
		}
	}

	public static Cipher getCipher(String algorithm, Provider provider) {
		try {
			return Cipher.getInstance(getMainAlgorithm(algorithm), provider);
		} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
			throw new CryptoRuntimeException(e);
		}
	}

	/**
	 * 获取主体算法名,例如RSA/ECB/PKCS1Padding的主体算法是RSA
	 *
	 * @param algorithm XXXwithXXX算法
	 * @return 主体算法名
	 */
	public static String getMainAlgorithm(@Nonnull String algorithm) {
		final int slashIndex = algorithm.indexOf(CharConsts.SLASH);
		if (slashIndex > 0) {
			return algorithm.substring(0, slashIndex);
		}
		return algorithm;
	}

	/**
	 * 获取用于密钥生成的算法
* 获取XXXwithXXX算法的后半部分算法,如果为ECDSA或SM2,返回算法为EC * * @param algorithm XXXwithXXX算法 * @return 算法 */ public static String getAlgorithmAfterWith(String algorithm) { if (Strings.startsWithIgnoreCase(algorithm, "ECIESWith")) { return "EC"; } int indexOfWith = Strings.lastIndexOfIgnoreCase(algorithm, "with"); if (indexOfWith > 0) { algorithm = algorithm.substring(indexOfWith + "with".length()); } if ("ECDSA".equalsIgnoreCase(algorithm) || "SM2".equalsIgnoreCase(algorithm) || "ECIES".equalsIgnoreCase(algorithm) ) { algorithm = "EC"; } return algorithm; } // endregion // region 生成对称加密或摘要算法密钥 /** * 生成 {@link SecretKey},仅用于对称加密和摘要算法密钥生成 * * @param algorithm 算法,支持PBE算法 * @return {@link SecretKey} */ public static SecretKey generateKey(String algorithm) { return generateKey(algorithm, -1); } public static SecretKey generateKey(String provider, String algorithm) { return generateKey(provider, algorithm, -1); } public static SecretKey generateKey(Provider provider, String algorithm) { return generateKey(provider, algorithm, -1); } /** * 生成 {@link SecretKey},仅用于对称加密和摘要算法密钥生成
* 当指定keySize<0时,AES默认长度为128,其它算法不指定。 * * @param algorithm 算法,支持PBE算法 * @param keySize 密钥长度,<0表示不设定密钥长度,即使用默认长度 * @return {@link SecretKey} */ public static SecretKey generateKey(String algorithm, int keySize) { return generateKey(algorithm, keySize, (SecureRandom) null); } public static SecretKey generateKey(String provider, String algorithm, int keySize) { return generateKey(provider, algorithm, keySize, (SecureRandom) null); } public static SecretKey generateKey(Provider provider, String algorithm, int keySize) { return generateKey(provider, algorithm, keySize, (SecureRandom) null); } /** * 生成 {@link SecretKey},仅用于对称加密和摘要算法密钥生成
* 当指定keySize<0时,AES默认长度为128,其它算法不指定。 * * @param algorithm 算法,支持PBE算法 * @param keySize 密钥长度,<0表示不设定密钥长度,即使用默认长度 * @param random 随机数生成器,null表示默认 * @return {@link SecretKey} */ public static SecretKey generateKey(String algorithm, int keySize, SecureRandom random) { algorithm = getMainAlgorithm(algorithm); final KeyGenerator keyGenerator = getKeyGenerator(algorithm); if (keySize <= 0 && SymmetricAlgorithm.AES.code().equals(algorithm)) { // 对于AES的密钥,除非指定,否则强制使用128位 keySize = 128; } if (keySize > 0) { if (null == random) { keyGenerator.init(keySize); } else { keyGenerator.init(keySize, random); } } return keyGenerator.generateKey(); } public static SecretKey generateKey(String provider, String algorithm, int keySize, SecureRandom random) { algorithm = getMainAlgorithm(algorithm); final KeyGenerator keyGenerator = getKeyGenerator(algorithm, provider); if (keySize <= 0 && SymmetricAlgorithm.AES.code().equals(algorithm)) { // 对于AES的密钥,除非指定,否则强制使用128位 keySize = 128; } if (keySize > 0) { if (null == random) { keyGenerator.init(keySize); } else { keyGenerator.init(keySize, random); } } return keyGenerator.generateKey(); } public static SecretKey generateKey(Provider provider, String algorithm, int keySize, SecureRandom random) { algorithm = getMainAlgorithm(algorithm); final KeyGenerator keyGenerator = getKeyGenerator(algorithm, provider); if (keySize <= 0 && SymmetricAlgorithm.AES.code().equals(algorithm)) { // 对于AES的密钥,除非指定,否则强制使用128位 keySize = 128; } if (keySize > 0) { if (null == random) { keyGenerator.init(keySize); } else { keyGenerator.init(keySize, random); } } return keyGenerator.generateKey(); } /** * 生成 {@link SecretKey},仅用于对称加密和摘要算法密钥生成 * * @param algorithm 算法 * @param key 密钥,如果为{@code null} 自动生成随机密钥 * @return {@link SecretKey} */ public static SecretKey generateKey(String algorithm, byte[] key) { SecretKey secretKey; if (algorithm.startsWith("PBE")) { // PBE密钥 secretKey = generatePBEKey(algorithm, (null == key) ? null : new String(key, StandardCharsets.UTF_8).toCharArray()); } else if (algorithm.startsWith("DES")) { // DES密钥 secretKey = generateDESKey(algorithm, key); } else { // 其它算法密钥 secretKey = (null == key) ? generateKey(algorithm) : new SecretKeySpec(key, algorithm); } return secretKey; } public static SecretKey generateKey(String provider, String algorithm, byte[] key) { SecretKey secretKey; if (algorithm.startsWith("PBE")) { // PBE密钥 secretKey = generatePBEKey(provider, algorithm, (null == key) ? null : new String(key, StandardCharsets.UTF_8).toCharArray()); } else if (algorithm.startsWith("DES")) { // DES密钥 secretKey = generateDESKey(provider, algorithm, key); } else { // 其它算法密钥 secretKey = (null == key) ? generateKey(provider, algorithm) : new SecretKeySpec(key, algorithm); } return secretKey; } public static SecretKey generateKey(Provider provider, String algorithm, byte[] key) { SecretKey secretKey; if (algorithm.startsWith("PBE")) { // PBE密钥 secretKey = generatePBEKey(provider, algorithm, (null == key) ? null : new String(key, StandardCharsets.UTF_8).toCharArray()); } else if (algorithm.startsWith("DES")) { // DES密钥 secretKey = generateDESKey(provider, algorithm, key); } else { // 其它算法密钥 secretKey = (null == key) ? generateKey(provider, algorithm) : new SecretKeySpec(key, algorithm); } return secretKey; } public static SecretKey generateKeyBySeed(String algorithm, byte[] seed) { if (seed == null) { return generateKey(algorithm); } KeyGenerator keyGen = getKeyGenerator(algorithm); keyGen.init(new SecureRandom(seed)); return keyGen.generateKey(); } public static SecretKey generateKeyBySeed(String provider, String algorithm, byte[] seed) { if (seed == null) { return generateKey(algorithm); } KeyGenerator keyGen = getKeyGenerator(algorithm, provider); keyGen.init(new SecureRandom(seed)); return keyGen.generateKey(); } public static SecretKey generateKeyBySeed(Provider provider, String algorithm, byte[] seed) { if (seed == null) { return generateKey(algorithm); } KeyGenerator keyGen = getKeyGenerator(algorithm, provider); keyGen.init(new SecureRandom(seed)); return keyGen.generateKey(); } /** * 生成PBE {@link SecretKey} * * @param algorithm PBE算法,包括:PBEWithMD5AndDES、PBEWithSHA1AndDESede、PBEWithSHA1AndRC2_40等 * @param key 密钥 * @return {@link SecretKey} */ public static SecretKey generatePBEKey(String algorithm, char[] key) { if (Strings.isNotBlank(algorithm) || !algorithm.startsWith("PBE")) { throw new IllegalArgumentException("Not PBE algorithm!"); } if (key == null) { key = Randoms.randomString(32).toCharArray(); } PBEKeySpec keySpec = new PBEKeySpec(key); return generateKey(algorithm, keySpec); } public static SecretKey generatePBEKey(String provider, String algorithm, char[] key) { if (Strings.isNotBlank(algorithm) || !algorithm.startsWith("PBE")) { throw new IllegalArgumentException("Not PBE algorithm!"); } if (key == null) { key = Randoms.randomString(32).toCharArray(); } PBEKeySpec keySpec = new PBEKeySpec(key); return generateKey(provider, algorithm, keySpec); } public static SecretKey generatePBEKey(Provider provider, String algorithm, char[] key) { if (Strings.isNotBlank(algorithm) || !algorithm.startsWith("PBE")) { throw new IllegalArgumentException("Not PBE algorithm!"); } if (key == null) { key = Randoms.randomString(32).toCharArray(); } PBEKeySpec keySpec = new PBEKeySpec(key); return generateKey(provider, algorithm, keySpec); } /** * 生成 {@link SecretKey} * * @param algorithm DES算法,包括DES、DESede等 * @param key 密钥 * @return {@link SecretKey} */ public static SecretKey generateDESKey(String algorithm, byte[] key) { if (Strings.isBlank(algorithm) || !algorithm.startsWith("DES")) { throw new IllegalArgumentException("Not DES algorithm!"); } try { SecretKey secretKey; if (null == key) { secretKey = generateKey(algorithm); } else { KeySpec keySpec; // 兼容 DESede if (algorithm.startsWith("DESede")) { keySpec = new DESedeKeySpec(key); } else { keySpec = new DESKeySpec(key); } secretKey = generateKey(algorithm, keySpec); } return secretKey; } catch (InvalidKeyException e) { throw new CryptoRuntimeException(e); } } public static SecretKey generateDESKey(String provider, String algorithm, byte[] key) { if (Strings.isBlank(algorithm) || !algorithm.startsWith("DES")) { throw new IllegalArgumentException("Not DES algorithm!"); } try { SecretKey secretKey; if (null == key) { secretKey = generateKey(provider, algorithm); } else { KeySpec keySpec; // 兼容 DESede if (algorithm.startsWith("DESede")) { keySpec = new DESedeKeySpec(key); } else { keySpec = new DESKeySpec(key); } secretKey = generateKey(provider, algorithm, keySpec); } return secretKey; } catch (InvalidKeyException e) { throw new CryptoRuntimeException(e); } } public static SecretKey generateDESKey(Provider provider, String algorithm, byte[] key) { if (Strings.isBlank(algorithm) || !algorithm.startsWith("DES")) { throw new IllegalArgumentException("Not DES algorithm!"); } try { SecretKey secretKey; if (null == key) { secretKey = generateKey(provider, algorithm); } else { KeySpec keySpec; // 兼容 DESede if (algorithm.startsWith("DESede")) { keySpec = new DESedeKeySpec(key); } else { keySpec = new DESKeySpec(key); } secretKey = generateKey(provider, algorithm, keySpec); } return secretKey; } catch (InvalidKeyException e) { throw new CryptoRuntimeException(e); } } /** * 生成 {@link SecretKey},仅用于对称加密和摘要算法 * * @param algorithm 算法 * @param keySpec {@link KeySpec} * @return {@link SecretKey} */ public static SecretKey generateKey(String algorithm, KeySpec keySpec) { final SecretKeyFactory keyFactory = getSecretKeyFactory(algorithm); try { return keyFactory.generateSecret(keySpec); } catch (InvalidKeySpecException e) { throw new CryptoRuntimeException(e); } } public static SecretKey generateKey(String provider, String algorithm, KeySpec keySpec) { final SecretKeyFactory keyFactory = getSecretKeyFactory(algorithm, provider); try { return keyFactory.generateSecret(keySpec); } catch (InvalidKeySpecException e) { throw new CryptoRuntimeException(e); } } public static SecretKey generateKey(Provider provider, String algorithm, KeySpec keySpec) { final SecretKeyFactory keyFactory = getSecretKeyFactory(algorithm, provider); try { return keyFactory.generateSecret(keySpec); } catch (InvalidKeySpecException e) { throw new CryptoRuntimeException(e); } } // endregion // region 生成非对称加密密钥 /** * 生成RSA私钥,仅用于非对称加密
* 采用PKCS#8规范,此规范定义了私钥信息语法和加密私钥语法
* * @param key 密钥,必须为DER编码存储 * @return RSA私钥 {@link PrivateKey} */ public static PrivateKey generateRSAPrivateKey(@Nonnull byte[] key) { return generatePrivateKey(AsymmetricAlgorithm.RSA.code(), key); } public static PrivateKey generateRSAPrivateKey(String provider, @Nonnull byte[] key) { return generatePrivateKey(provider, AsymmetricAlgorithm.RSA.code(), key); } public static PrivateKey generateRSAPrivateKey(Provider provider, @Nonnull byte[] key) { return generatePrivateKey(provider, AsymmetricAlgorithm.RSA.code(), key); } /** * 生成私钥,仅用于非对称加密
* 采用PKCS#8规范,此规范定义了私钥信息语法和加密私钥语法
* * @param algorithm 算法,如RSA、EC、SM2等 * @param key 密钥,PKCS#8格式 * @return 私钥 {@link PrivateKey} */ public static PrivateKey generatePrivateKey(@Nonnull String algorithm, @Nonnull byte[] key) { return generatePrivateKey(algorithm, new PKCS8EncodedKeySpec(key)); } public static PrivateKey generatePrivateKey(String provider, @Nonnull String algorithm, @Nonnull byte[] key) { return generatePrivateKey(provider, algorithm, new PKCS8EncodedKeySpec(key)); } public static PrivateKey generatePrivateKey(Provider provider, @Nonnull String algorithm, @Nonnull byte[] key) { return generatePrivateKey(provider, algorithm, new PKCS8EncodedKeySpec(key)); } /** * 生成私钥,仅用于非对称加密
* * @param algorithm 算法,如RSA、EC、SM2等 * @param keySpec {@link KeySpec} * @return 私钥 {@link PrivateKey} */ public static PrivateKey generatePrivateKey(@Nonnull String algorithm, @Nonnull KeySpec keySpec) { algorithm = getAlgorithmAfterWith(algorithm); try { return getKeyFactory(algorithm).generatePrivate(keySpec); } catch (InvalidKeySpecException e) { throw new CryptoRuntimeException(e); } } public static PrivateKey generatePrivateKey(String provider, @Nonnull String algorithm, @Nonnull KeySpec keySpec) { algorithm = getAlgorithmAfterWith(algorithm); try { return getKeyFactory(algorithm, provider).generatePrivate(keySpec); } catch (InvalidKeySpecException e) { throw new CryptoRuntimeException(e); } } public static PrivateKey generatePrivateKey(Provider provider, @Nonnull String algorithm, @Nonnull KeySpec keySpec) { algorithm = getAlgorithmAfterWith(algorithm); try { return getKeyFactory(algorithm, provider).generatePrivate(keySpec); } catch (InvalidKeySpecException e) { throw new CryptoRuntimeException(e); } } /** * 生成RSA公钥,仅用于非对称加密
* 采用X509证书规范
* * @param key 密钥,必须为DER编码存储 * @return 公钥 {@link PublicKey} */ public static PublicKey generateRSAPublicKey(@Nonnull byte[] key) { return generatePublicKey(AsymmetricAlgorithm.RSA.code(), key); } public static PublicKey generateRSAPublicKey(String provider, @Nonnull byte[] key) { return generatePublicKey(provider, AsymmetricAlgorithm.RSA.code(), key); } public static PublicKey generateRSAPublicKey(Provider provider, @Nonnull byte[] key) { return generatePublicKey(provider, AsymmetricAlgorithm.RSA.code(), key); } /** * 生成公钥,仅用于非对称加密
* 采用X509证书规范
* * @param algorithm 算法 * @param key 密钥,必须为DER编码存储 * @return 公钥 {@link PublicKey} */ public static PublicKey generatePublicKey(String algorithm, byte[] key) { return generatePublicKey(algorithm, new X509EncodedKeySpec(key)); } public static PublicKey generatePublicKey(String provider, String algorithm, byte[] key) { return generatePublicKey(provider, algorithm, new X509EncodedKeySpec(key)); } public static PublicKey generatePublicKey(Provider provider, String algorithm, byte[] key) { return generatePublicKey(provider, algorithm, new X509EncodedKeySpec(key)); } /** * 生成公钥,仅用于非对称加密
* * @param algorithm 算法 * @param keySpec {@link KeySpec} * @return 公钥 {@link PublicKey} */ public static PublicKey generatePublicKey(String algorithm, KeySpec keySpec) { algorithm = getAlgorithmAfterWith(algorithm); try { return getKeyFactory(algorithm).generatePublic(keySpec); } catch (InvalidKeySpecException e) { throw new CryptoRuntimeException(e); } } public static PublicKey generatePublicKey(String provider, String algorithm, KeySpec keySpec) { algorithm = getAlgorithmAfterWith(algorithm); try { return getKeyFactory(algorithm, provider).generatePublic(keySpec); } catch (InvalidKeySpecException e) { throw new CryptoRuntimeException(e); } } public static PublicKey generatePublicKey(Provider provider, String algorithm, KeySpec keySpec) { algorithm = getAlgorithmAfterWith(algorithm); try { return getKeyFactory(algorithm, provider).generatePublic(keySpec); } catch (InvalidKeySpecException e) { throw new CryptoRuntimeException(e); } } /** * 生成用于非对称加密的公钥和私钥,仅用于非对称加密 * * @param algorithm 非对称加密算法 * @return {@link KeyPair} */ public static KeyPair generateKeyPair(String algorithm) { // ECIES算法对KEY的长度有要求,此处默认256 int keySize = "ECIES".equalsIgnoreCase(algorithm) ? 256 : DEFAULT_KEY_SIZE; return generateKeyPair(algorithm, keySize); } public static KeyPair generateKeyPair(String provider, String algorithm) { // ECIES算法对KEY的长度有要求,此处默认256 int keySize = "ECIES".equalsIgnoreCase(algorithm) ? 256 : DEFAULT_KEY_SIZE; return generateKeyPair(provider, algorithm, keySize); } public static KeyPair generateKeyPair(Provider provider, String algorithm) { // ECIES算法对KEY的长度有要求,此处默认256 int keySize = "ECIES".equalsIgnoreCase(algorithm) ? 256 : DEFAULT_KEY_SIZE; return generateKeyPair(provider, algorithm, keySize); } /** * 生成用于非对称加密的公钥和私钥 * * @param algorithm 非对称加密算法 * @param keySize 密钥模(modulus )长度 * @return {@link KeyPair} */ public static KeyPair generateKeyPair(String algorithm, int keySize) { return generateKeyPair(algorithm, keySize, null); } public static KeyPair generateKeyPair(String provider, String algorithm, int keySize) { return generateKeyPair(provider, algorithm, keySize, null); } public static KeyPair generateKeyPair(Provider provider, String algorithm, int keySize) { return generateKeyPair(provider, algorithm, keySize, null); } /** * 生成用于非对称加密的公钥和私钥 * * @param algorithm 非对称加密算法 * @param keySize 密钥模(modulus )长度 * @param seed 种子 * @return {@link KeyPair} */ public static KeyPair generateKeyPair(String algorithm, int keySize, byte[] seed) { // SM2算法需要单独定义其曲线生成 if ("SM2".equalsIgnoreCase(algorithm)) { final ECGenParameterSpec sm2p256v1 = new ECGenParameterSpec(SM2_DEFAULT_CURVE); return generateKeyPair(algorithm, keySize, seed, sm2p256v1); } return generateKeyPair(algorithm, keySize, seed, (AlgorithmParameterSpec[]) null); } public static KeyPair generateKeyPair(String provider, String algorithm, int keySize, byte[] seed) { // SM2算法需要单独定义其曲线生成 if ("SM2".equalsIgnoreCase(algorithm)) { final ECGenParameterSpec sm2p256v1 = new ECGenParameterSpec(SM2_DEFAULT_CURVE); return generateKeyPair(algorithm, keySize, seed, sm2p256v1); } return generateKeyPair(provider, algorithm, keySize, seed, (AlgorithmParameterSpec[]) null); } public static KeyPair generateKeyPair(Provider provider, String algorithm, int keySize, byte[] seed) { // SM2算法需要单独定义其曲线生成 if ("SM2".equalsIgnoreCase(algorithm)) { final ECGenParameterSpec sm2p256v1 = new ECGenParameterSpec(SM2_DEFAULT_CURVE); return generateKeyPair(algorithm, keySize, seed, sm2p256v1); } return generateKeyPair(provider, algorithm, keySize, seed, (AlgorithmParameterSpec[]) null); } /** * 生成用于非对称加密的公钥和私钥 * * @param algorithm 非对称加密算法 * @param params {@link AlgorithmParameterSpec} * @return {@link KeyPair} */ public static KeyPair generateKeyPair(String algorithm, AlgorithmParameterSpec params) { return generateKeyPair(algorithm, (byte[]) null, params); } public static KeyPair generateKeyPair(String provider, String algorithm, AlgorithmParameterSpec params) { return generateKeyPair(provider, algorithm, (byte[]) null, params); } public static KeyPair generateKeyPair(Provider provider, String algorithm, AlgorithmParameterSpec params) { return generateKeyPair(provider, algorithm, (byte[]) null, params); } /** * 生成用于非对称加密的公钥和私钥 * * @param algorithm 非对称加密算法 * @param param {@link AlgorithmParameterSpec} * @param seed 种子 * @return {@link KeyPair} */ public static KeyPair generateKeyPair(String algorithm, byte[] seed, AlgorithmParameterSpec param) { return generateKeyPair(algorithm, DEFAULT_KEY_SIZE, seed, param); } public static KeyPair generateKeyPair(String provider, String algorithm, byte[] seed, AlgorithmParameterSpec param) { return generateKeyPair(provider, algorithm, DEFAULT_KEY_SIZE, seed, param); } public static KeyPair generateKeyPair(Provider provider, String algorithm, byte[] seed, AlgorithmParameterSpec param) { return generateKeyPair(provider, algorithm, DEFAULT_KEY_SIZE, seed, param); } /** * 生成用于非对称加密的公钥和私钥 * * @param algorithm 非对称加密算法 * @param keySize 密钥模(modulus )长度(单位bit) * @param seed 种子 * @param params {@link AlgorithmParameterSpec} * @return {@link KeyPair} */ public static KeyPair generateKeyPair(String algorithm, int keySize, byte[] seed, AlgorithmParameterSpec... params) { return generateKeyPair(algorithm, keySize, Randoms.createSecureRandom(seed), params); } public static KeyPair generateKeyPair(String provider, String algorithm, int keySize, byte[] seed, AlgorithmParameterSpec... params) { return generateKeyPair(provider, algorithm, keySize, Randoms.createSecureRandom(seed), params); } public static KeyPair generateKeyPair(Provider provider, String algorithm, int keySize, byte[] seed, AlgorithmParameterSpec... params) { return generateKeyPair(provider, algorithm, keySize, Randoms.createSecureRandom(seed), params); } /** * 生成用于非对称加密的公钥和私钥
* 密钥对生成算法见:https://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#KeyPairGenerator * *

* 对于非对称加密算法,密钥长度有严格限制,具体如下: * *

* RSA: *

	 * RS256、PS256:2048 bits
	 * RS384、PS384:3072 bits
	 * RS512、RS512:4096 bits
	 * 
* *

* EC(Elliptic Curve): *

	 * EC256:256 bits
	 * EC384:384 bits
	 * EC512:512 bits
	 * 
* * @param algorithm 非对称加密算法 * @param keySize 密钥模(modulus )长度(单位bit) * @param random {@link SecureRandom} 对象,创建时可选传入seed * @param params {@link AlgorithmParameterSpec} * @return {@link KeyPair} */ public static KeyPair generateKeyPair(String algorithm, int keySize, SecureRandom random, AlgorithmParameterSpec... params) { algorithm = getAlgorithmAfterWith(algorithm); final KeyPairGenerator keyPairGen = getKeyPairGenerator(algorithm); return getKeyPair(keyPairGen, algorithm, keySize, random, params); } public static KeyPair generateKeyPair(String provider, String algorithm, int keySize, SecureRandom random, AlgorithmParameterSpec... params) { algorithm = getAlgorithmAfterWith(algorithm); final KeyPairGenerator keyPairGen = getKeyPairGenerator(algorithm, provider); return getKeyPair(keyPairGen, algorithm, keySize, random, params); } public static KeyPair generateKeyPair(Provider provider, String algorithm, int keySize, SecureRandom random, AlgorithmParameterSpec... params) { algorithm = getAlgorithmAfterWith(algorithm); final KeyPairGenerator keyPairGen = getKeyPairGenerator(algorithm, provider); return getKeyPair(keyPairGen, algorithm, keySize, random, params); } private static KeyPair getKeyPair(KeyPairGenerator keyPairGen, String algorithm, int keySize, SecureRandom random, AlgorithmParameterSpec[] params) { try { // 密钥模(modulus )长度初始化定义 if (keySize > 0) { // key长度适配修正 if ("EC".equalsIgnoreCase(algorithm) && keySize > 256) { // 对于EC(EllipticCurve)算法,密钥长度有限制,在此使用默认256 keySize = 256; } if (null != random) { keyPairGen.initialize(keySize, random); } else { keyPairGen.initialize(keySize); } } // 自定义初始化参数 if (Iterables.isNotEmpty(params)) { for (AlgorithmParameterSpec param : params) { if (null == param) { continue; } if (null != random) { keyPairGen.initialize(param, random); } else { keyPairGen.initialize(param); } } } return keyPairGen.generateKeyPair(); } catch (InvalidAlgorithmParameterException e) { throw new CryptoRuntimeException(e); } } // endregion // region 非对称公私密钥转换 public static PrivateKey toPrivateKey(String algorithm, byte[] key) { try { return getKeyFactory(algorithm).generatePrivate(new PKCS8EncodedKeySpec(key)); } catch (InvalidKeySpecException e) { throw new CryptoRuntimeException(e); } } public static PrivateKey toPrivateKey(String provider, String algorithm, byte[] key) { try { return getKeyFactory(algorithm, provider).generatePrivate(new PKCS8EncodedKeySpec(key)); } catch (InvalidKeySpecException e) { throw new CryptoRuntimeException(e); } } public static PrivateKey toPrivateKey(Provider provider, String algorithm, byte[] key) { try { return getKeyFactory(algorithm, provider).generatePrivate(new PKCS8EncodedKeySpec(key)); } catch (InvalidKeySpecException e) { throw new CryptoRuntimeException(e); } } public static PublicKey toPublicKey(String algorithm, byte[] key) { try { return getKeyFactory(algorithm).generatePublic(new X509EncodedKeySpec(key)); } catch (InvalidKeySpecException e) { throw new CryptoRuntimeException(e); } } public static PublicKey toPublicKey(String provider, String algorithm, byte[] key) { try { return getKeyFactory(algorithm, provider).generatePublic(new X509EncodedKeySpec(key)); } catch (InvalidKeySpecException e) { throw new CryptoRuntimeException(e); } } public static PublicKey toPublicKey(Provider provider, String algorithm, byte[] key) { try { return getKeyFactory(algorithm, provider).generatePublic(new X509EncodedKeySpec(key)); } catch (InvalidKeySpecException e) { throw new CryptoRuntimeException(e); } } public static RSAPrivateKey toRSAPrivateKey(RSAPublicKey rsaPublicKey) { try { return (RSAPrivateKey) getKeyFactory(AsymmetricAlgorithm.RSA.code()) .generatePrivate(new RSAPrivateKeySpec(rsaPublicKey.getModulus(), rsaPublicKey.getPublicExponent())); } catch (InvalidKeySpecException e) { throw new CryptoRuntimeException(e); } } public static RSAPrivateKey toRSAPrivateKey(String provider, RSAPublicKey rsaPublicKey) { try { return (RSAPrivateKey) getKeyFactory(AsymmetricAlgorithm.RSA.code(), provider) .generatePrivate(new RSAPrivateKeySpec(rsaPublicKey.getModulus(), rsaPublicKey.getPublicExponent())); } catch (InvalidKeySpecException e) { throw new CryptoRuntimeException(e); } } public static RSAPrivateKey toRSAPrivateKey(Provider provider, RSAPublicKey rsaPublicKey) { try { return (RSAPrivateKey) getKeyFactory(AsymmetricAlgorithm.RSA.code(), provider) .generatePrivate(new RSAPrivateKeySpec(rsaPublicKey.getModulus(), rsaPublicKey.getPublicExponent())); } catch (InvalidKeySpecException e) { throw new CryptoRuntimeException(e); } } public static RSAPublicKey toRSAPublicKey(RSAPrivateKey rsaPrivateKey) { try { return (RSAPublicKey) getKeyFactory(AsymmetricAlgorithm.RSA.code()) .generatePrivate(new RSAPublicKeySpec(rsaPrivateKey.getModulus(), rsaPrivateKey.getPrivateExponent())); } catch (InvalidKeySpecException e) { throw new CryptoRuntimeException(e); } } public static RSAPublicKey toRSAPublicKey(String provider, RSAPrivateKey rsaPrivateKey) { try { return (RSAPublicKey) getKeyFactory(AsymmetricAlgorithm.RSA.code(), provider) .generatePrivate(new RSAPublicKeySpec(rsaPrivateKey.getModulus(), rsaPrivateKey.getPrivateExponent())); } catch (InvalidKeySpecException e) { throw new CryptoRuntimeException(e); } } public static RSAPublicKey toRSAPublicKey(Provider provider, RSAPrivateKey rsaPrivateKey) { try { return (RSAPublicKey) getKeyFactory(AsymmetricAlgorithm.RSA.code(), provider) .generatePrivate(new RSAPublicKeySpec(rsaPrivateKey.getModulus(), rsaPrivateKey.getPrivateExponent())); } catch (InvalidKeySpecException e) { throw new CryptoRuntimeException(e); } } public static RSAPrivateKey toRSAPrivateKey(byte[] modulus, byte[] publicExponent) { try { return (RSAPrivateKey) getKeyFactory(AsymmetricAlgorithm.RSA.code()) .generatePrivate(new RSAPrivateKeySpec(new BigInteger(modulus), new BigInteger(publicExponent))); } catch (InvalidKeySpecException e) { throw new CryptoRuntimeException(e); } } public static RSAPublicKey toRSAPublicKey(byte[] modulus, byte[] publicExponent) { try { return (RSAPublicKey) getKeyFactory(AsymmetricAlgorithm.RSA.code()) .generatePublic(new RSAPublicKeySpec(new BigInteger(modulus), new BigInteger(publicExponent))); } catch (InvalidKeySpecException e) { throw new CryptoRuntimeException(e); } } // endregion // region 读写文件密钥 /** * 生成私钥,仅用于非对称加密 * * @param keyStore {@link KeyStore} * @param alias 别名 * @param password 密码 * @return 私钥 {@link PrivateKey} */ public static PrivateKey readPrivateKey(KeyStore keyStore, String alias, char[] password) { try { return (PrivateKey) keyStore.getKey(alias, password); } catch (KeyStoreException | NoSuchAlgorithmException | UnrecoverableKeyException e) { throw new CryptoRuntimeException(e); } } public static PublicKey readPublicKeyByX509(String x509File) throws IOException { try (InputStream in = IO.getInputStream(x509File)) { CertificateFactory factory = CertificateFactory.getInstance(CERT_TYPE_X509); Certificate cer = factory.generateCertificate(in); return cer.getPublicKey(); } catch (CertificateException e) { throw new CryptoRuntimeException(e); } } public static PublicKey readPublicKeyByX509(InputStream in) { final Certificate certificate = readX509Certificate(in); if (null != certificate) { return certificate.getPublicKey(); } return null; } public static PublicKey readPublicKeyFile(String algorithm, String file) throws IOException { try (InputStream in = IO.getInputStream(file)) { byte[] publicKeyBytes = IO.toBytes(in, 64); return toPublicKey(algorithm, publicKeyBytes); } } /** * 读取密钥库(Java Key Store,JKS) KeyStore文件
* KeyStore文件用于数字证书的密钥对保存 * * @param keyFile 密钥库文件 * @param password 密码 * @return {@link KeyStore} */ public static KeyStore readJKSKeyStore(File keyFile, char[] password) throws IOException { return readKeyStore(KEY_TYPE_JKS, keyFile, password); } /** * 读取密钥库(Java Key Store,JKS) KeyStore文件
* KeyStore文件用于数字证书的密钥对保存 * * @param in 证书文件 * @param password 密码 * @return {@link KeyStore} */ public static KeyStore readJKSKeyStore(InputStream in, char[] password) throws IOException { return readKeyStore(KEY_TYPE_JKS, in, password); } /** * 读取PKCS12 KeyStore文件
* KeyStore文件用于数字证书的密钥对保存 * * @param keyFile 证书文件 * @param password 密码 * @return {@link KeyStore} */ public static KeyStore readPKCS12KeyStore(File keyFile, char[] password) throws IOException { return readKeyStore(KEY_TYPE_PKCS12, keyFile, password); } /** * 读取PKCS12 KeyStore文件
* KeyStore文件用于数字证书的密钥对保存 * * @param in 证书文件 * @param password 密码 * @return {@link KeyStore} */ public static KeyStore readPKCS12KeyStore(InputStream in, char[] password) throws IOException { return readKeyStore(KEY_TYPE_PKCS12, in, password); } /** * 读取KeyStore文件
* KeyStore文件用于数字证书的密钥对保存 * * @param type 类型 * @param keyFile 证书文件 * @param password 密码,null表示无密码 * @return {@link KeyStore} */ public static KeyStore readKeyStore(String type, File keyFile, char[] password) throws IOException { InputStream in = null; try { in = IO.getInputStream(keyFile); return readKeyStore(type, in, password); } finally { IO.close(in); } } /** * 读取KeyStore文件
* KeyStore文件用于数字证书的密钥对保存 * * @param type 类型 * @param in 证书文件 * @param password 密码,null表示无密码 * @return {@link KeyStore} */ public static KeyStore readKeyStore(String type, InputStream in, char[] password) throws IOException { try { final KeyStore keyStore = getKeyStore(type); keyStore.load(in, password); return keyStore; } catch (NoSuchAlgorithmException | CertificateException e) { throw new CryptoRuntimeException(e); } } /** * 获取{@link KeyStore}对象 * * @param type 类型 * @return {@link KeyStore} */ public static KeyStore getKeyStore(final String type) { try { return KeyStore.getInstance(type); } catch (KeyStoreException e) { throw new CryptoRuntimeException(e); } } /** * 从KeyStore中获取私钥公钥 * * @param type 类型 * @param in 证书文件 * @param password 密码 * @param alias 别名 * @return {@link KeyPair} */ public static KeyPair getKeyPair(String type, InputStream in, char[] password, String alias) throws IOException { final KeyStore keyStore = readKeyStore(type, in, password); return getKeyPair(keyStore, password, alias); } /** * 从KeyStore中获取私钥公钥 * * @param keyStore {@link KeyStore} * @param password 密码 * @param alias 别名 * @return {@link KeyPair} */ public static KeyPair getKeyPair(KeyStore keyStore, char[] password, String alias) { try { PublicKey publicKey = keyStore.getCertificate(alias).getPublicKey(); PrivateKey privateKey = (PrivateKey) keyStore.getKey(alias, password); return new KeyPair(publicKey, privateKey); } catch (KeyStoreException | NoSuchAlgorithmException | UnrecoverableKeyException e) { throw new CryptoRuntimeException(e); } } /** * 读取X.509 Certification文件 * * @param in 证书文件 * @param password 密码 * @param alias 别名 * @return {@link KeyStore} */ public static Certificate readX509Certificate(InputStream in, char[] password, String alias) throws IOException { return readCertificate(CERT_TYPE_X509, in, password, alias); } /** * 读取X.509 Certification文件 */ public static Certificate readX509Certificate(InputStream in) { return readCertificate(CERT_TYPE_X509, in); } public static Certificate readCertificate(String type, InputStream in, char[] password, String alias) throws IOException { final KeyStore keyStore = readKeyStore(type, in, password); try { return keyStore.getCertificate(alias); } catch (KeyStoreException e) { throw new CryptoRuntimeException(e); } } public static Certificate readCertificate(String type, InputStream in) { try { return getCertificateFactory(type).generateCertificate(in); } catch (CertificateException e) { throw new CryptoRuntimeException(e); } } public static Certificate getCertificate(KeyStore keyStore, String alias) { try { return keyStore.getCertificate(alias); } catch (KeyStoreException e) { throw new CryptoRuntimeException(e); } } public static CertificateFactory getCertificateFactory(String type) { try { return CertificateFactory.getInstance(type); } catch (CertificateException e) { throw new CryptoRuntimeException(e); } } // endregion }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy