Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.gitee.apanlh.util.algorithm.encrypt.asymmetric.BouncyCastleAsymmetricAbstract Maven / Gradle / Ivy
package com.gitee.apanlh.util.algorithm.encrypt.asymmetric;
import com.gitee.apanlh.exp.algorithm.AsymmetricException;
import com.gitee.apanlh.util.algorithm.KeyUtils;
import com.gitee.apanlh.util.algorithm.encrypt.CipherMode;
import com.gitee.apanlh.util.base.ChooseOr;
import com.gitee.apanlh.util.base.Empty;
import com.gitee.apanlh.util.base.Eq;
import com.gitee.apanlh.util.encode.Base64Utils;
import com.gitee.apanlh.util.encode.HexUtils;
import com.gitee.apanlh.util.valid.Assert;
import com.gitee.apanlh.util.valid.ValidParam;
import org.bouncycastle.jcajce.provider.asymmetric.rsa.BCRSAPrivateKey;
import org.bouncycastle.jcajce.provider.asymmetric.rsa.BCRSAPublicKey;
import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.math.BigInteger;
import java.security.Key;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.PublicKey;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAKeyGenParameterSpec;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;
/**
* 非对称算法加密/解密抽象类
* 默认实现了加密和解密功能
* 该抽象类提供了对称加密算法的通用操作和方法,子类可以继承此类并根据具体的非对称加密算法实现相应的加密和解密逻辑。
* 该抽象类依赖于 Bouncy Castle提供的加密算法库,需要在使用前添加 Bouncy Castle作为加密算法提供者
* 注意:该类的部分方法参数或字段可能需要根据具体的对称加密算法进行调整和适配
* 参考文档:Bouncy Castle: ...
* TODO 区分BC以及JDK实现不同方式
* TODO BC是none 而JDK是 ECB
* @author Pan
*/
public abstract class BouncyCastleAsymmetricAbstract extends CustomAsymmetricAbstract implements AsymmetricEncode {
/** TODO 未来需要改造兼容JDK及BC 静态Provider */
Provider provider = null;
// static {
// CheckImport.library(CheckLibrary.BOUNCY_CASTLE);
// bouncyCastleProvider = new BouncyCastleProvider();
// Security.addProvider(bouncyCastleProvider);
// }
/** 算法类型 */
private AsymmetricType asymmetricType;
/** 算法名称 */
private String algorithm;
/** 加密器模式 */
private CipherMode cipherMode;
/** 加密器 */
private Cipher encryptCipher;
/** 解密器 */
private Cipher decryptCipher;
/** 公钥 */
private PublicKey publicKey;
/** 公钥字节 */
private byte[] publicKeyBytes;
/** 私钥 */
private PrivateKey privateKey;
/** 私钥字节 */
private byte[] privateKeyBytes;
/** 算法长度 */
private int keyLength;
/** 默认加密块大小 */
private int encryptBlockSize = 117;
/** 默认解密块大小 */
private int decryptBlockSize = 128;
/**
* 构造函数-初始化加解密器
*
* @author Pan
*/
protected BouncyCastleAsymmetricAbstract() {
super();
}
/**
* 构造函数-初始化非对称加密算法
* 默认采用算法模式比如RSA、SM2等等
* 默认生成1024位密钥长度
* 动态加载加解密器模式(加密模式、解密模式)
*
* @author Pan
* @param asymmetricType 非对称加密算法类型
*/
protected BouncyCastleAsymmetricAbstract(AsymmetricType asymmetricType) {
this.asymmetricType = asymmetricType;
this.algorithm = asymmetricType.getAlgorithm();
if (Eq.enums(AsymmetricType.RSA, asymmetricType)) {
initKeyPair(1024);
}
}
/**
* 构造函数-初始化非对称加密算法
* 自定义默认算法模式
* 如果字符串为hex或者base64编码格式将自动解码还原无需额外操作
* 如果只传递公钥可用于加密
* 如果只传递私钥可用于解密
* 动态加载加解密器模式(加密模式、解密模式)
*
* @author Pan
* @param publicKey 公钥字符串
* @param privateKey 私钥字符串
* @param asymmetricType 非对称加密算法类型
*/
protected BouncyCastleAsymmetricAbstract(String publicKey, String privateKey, AsymmetricType asymmetricType) {
Assert.isFalse(ValidParam.isEmpty(publicKey) && ValidParam.isEmpty(privateKey), "string key is not allowed to be empty at the same time");
this.asymmetricType = asymmetricType;
this.algorithm = asymmetricType.getAlgorithm();
if (ValidParam.isNotEmpty(publicKey)) {
this.publicKeyBytes = KeyUtils.decode(publicKey);
}
if (ValidParam.isNotEmpty(privateKey)) {
this.privateKeyBytes = KeyUtils.decode(privateKey);
}
}
/**
* 构造函数-初始化非对称加密算法
* 如果只传递公钥可用于加密
* 如果只传递私钥可用于解密
* 动态加载加解密器模式(加密模式、解密模式)
*
* @author Pan
* @param publicKey 公钥
* @param privateKey 私钥
* @param asymmetricType 非对称加密算法类型
*/
protected BouncyCastleAsymmetricAbstract(byte[] publicKey, byte[] privateKey, AsymmetricType asymmetricType) {
Assert.isFalse(ValidParam.isEmpty(publicKey) && ValidParam.isEmpty(privateKey), "key is not allowed to be empty at the same time");
this.asymmetricType = asymmetricType;
this.algorithm = asymmetricType.getAlgorithm();
this.publicKeyBytes = publicKey;
this.privateKeyBytes = privateKey;
}
/**
* 构造函数-初始化非对称加密算法
* 如果只传递公钥可用于加密
* 如果只传递私钥可用于解密
* 动态加载加解密器模式(加密模式、解密模式)
*
* @author Pan
* @param publicKey 公钥
* @param privateKey 私钥
* @param asymmetricType 非对称加密算法类型
*/
protected BouncyCastleAsymmetricAbstract(PublicKey publicKey, PrivateKey privateKey, AsymmetricType asymmetricType) {
Assert.isFalse(ValidParam.isNotNull(publicKey) && ValidParam.isNotNull(privateKey), "key is not allowed to be empty at the same time");
this.asymmetricType = asymmetricType;
this.algorithm = asymmetricType.getAlgorithm();
this.publicKey = publicKey;
this.privateKey = privateKey;
}
/**
* 构造函数-根据公共指数及特征值初始化非对称加密算法
* 如果只传递公钥特征值可用于加密
* 如果只传递私钥特征值可用于解密
* 动态加载加解密器模式(加密模式、解密模式)
*
* @author Pan
* @param modulus 公共指数
* @param publicExponent 公钥特征值
* @param privateExponent 私钥特征值
* @param asymmetricType 非对称加密算法类型
*/
protected BouncyCastleAsymmetricAbstract(BigInteger modulus, BigInteger publicExponent, BigInteger privateExponent, AsymmetricType asymmetricType) {
Assert.isNotNull(modulus);
Assert.isFalse(ValidParam.isNull(publicExponent) && ValidParam.isNull(privateExponent), "exponent is not allowed to be empty at the same time");
this.asymmetricType = asymmetricType;
this.algorithm = asymmetricType.getAlgorithm();
if (ValidParam.isNotNull(publicExponent)) {
this.publicKey = (PublicKey) getPublicKey(new RSAPublicKeySpec(modulus, publicExponent));
}
if (ValidParam.isNotNull(privateExponent)) {
this.privateKey = (PrivateKey) getPrivateKey(new RSAPrivateKeySpec(modulus, privateExponent));
}
}
@Override
public Cipher initCipher(byte[] publicKey, byte[] privateKey, CipherMode cipherMode) {
try {
Cipher cipher = null;
if (this.provider == null) {
cipher = Cipher.getInstance(getAlgorithm());
} else {
cipher = Cipher.getInstance(getAlgorithm(), getProvider());
}
cipher.init(cipherMode.getMode(), generateKey(publicKey, privateKey, cipherMode));
return setCipher(cipherMode, cipher);
} catch (Exception e) {
throw new AsymmetricException("load algorithm:{}, {}", e, this.algorithm, e.getMessage());
}
}
@Override
public KeyPair initKeyPair(int keyLength) {
KeyPair generateKeyPair = KeyUtils.generateKeyPair(getAlgorithm(), getProvider(), keyLength, new RSAKeyGenParameterSpec(keyLength, RSAKeyGenParameterSpec.F4));
this.privateKey = generateKeyPair.getPrivate();
this.publicKey = generateKeyPair.getPublic();
this.keyLength = keyLength;
return generateKeyPair;
}
@Override
public byte[] doFinal(CipherMode cipherMode, byte[] content) {
Cipher cipher = getCipher(cipherMode);
try {
int decryptBlockSize = getDecryptBlockSize();
int encryptBlockSize = getEncryptBlockSize();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
boolean hasEncrypt = Eq.enums(CipherMode.ENCRYPT, cipherMode);
int inputLen = content.length;
int offSet = 0;
byte[] buffer;
int i = 0;
// 数据分段加密/解密
while (inputLen - offSet > 0) {
if (inputLen - offSet > (hasEncrypt ? encryptBlockSize : decryptBlockSize)) {
buffer = cipher.doFinal(content, offSet, (hasEncrypt ? encryptBlockSize : decryptBlockSize));
} else {
buffer = cipher.doFinal(content, offSet, inputLen - offSet);
}
baos.write(buffer, 0, buffer.length);
i++;
offSet = i * (hasEncrypt ? encryptBlockSize : decryptBlockSize);
}
return baos.toByteArray();
} catch (Exception e) {
throw new AsymmetricException(e.getMessage(), e);
}
}
/**
* 设置加解密器
*
* @author Pan
* @param cipherMode 加解密器模式
* @param cipher 加解密器
* @return Cipher
*/
private Cipher setCipher(CipherMode cipherMode, Cipher cipher) {
if (Eq.enums(CipherMode.ENCRYPT, cipherMode)) {
this.encryptCipher = cipher;
} else {
this.decryptCipher = cipher;
}
return cipher;
}
/**
* 设置加密块大小
*
* @author Pan
* @param size 块长度
* @return int
*/
public int setEncryptBlockSize(int size) {
return setBlockSize(size, CipherMode.ENCRYPT);
}
/**
* 设置解密块大小
*
* @author Pan
* @param size 块长度
* @return int
*/
public int setDecryptBlockSize(int size) {
return setBlockSize(size, CipherMode.DECRYPT);
}
/**
* 设置加解密块大小
*
* @author Pan
* @param size 块长度
* @param cipherMode 模式
* @return int
*/
public int setBlockSize(int size, CipherMode cipherMode) {
if (Eq.enums(CipherMode.ENCRYPT, cipherMode)) {
this.encryptBlockSize = size;
} else {
this.decryptBlockSize = size;
}
return size;
}
/**
* 选择获取加解密器
*
* @author Pan
* @param cipherMode 加密器模式
* @return Cipher
*/
private Cipher getCipher(CipherMode cipherMode) {
if (Eq.enums(CipherMode.ENCRYPT, cipherMode)) {
if (this.encryptCipher == null) {
this.encryptCipher = initCipher(this.publicKeyBytes, this.privateKeyBytes, cipherMode);
}
return getEncryCipher();
}
if (this.decryptCipher == null) {
this.decryptCipher = initCipher(this.publicKeyBytes, this.privateKeyBytes, cipherMode);
}
return getDecryptCipher();
}
/**
* 获取加密器模式
*
* @author Pan
* @return CipherMode
*/
public CipherMode getCipherMode() {
return cipherMode;
}
/**
* 获取加密器
*
* @author Pan
* @return Cipher
*/
public Cipher getEncryCipher() {
return this.encryptCipher;
}
/**
* 获取解密器
*
* @author Pan
* @return Cipher
*/
public Cipher getDecryptCipher() {
return this.decryptCipher;
}
/**
* 获取非对称算法类型
*
* @author Pan
* @return AsymmetricType
*/
public AsymmetricType getAsymmetricType() {
return asymmetricType;
}
/**
* 获取算法名称
*
* @author Pan
* @return String
*/
public String getAlgorithm() {
return this.algorithm;
}
/**
* 获取算法长度
*
* @author Pan
* @return int
*/
public int getKeyLength() {
return keyLength;
}
@Override
public PublicKey getPublicKey() {
return this.publicKey;
}
@Override
public PrivateKey getPrivateKey() {
return this.privateKey;
}
/**
* 获取加密块
*
* @return int
*/
public int getEncryptBlockSize() {
return this.encryptBlockSize;
}
/**
* 获取解密块
*
* @return int
*/
public int getDecryptBlockSize() {
return this.decryptBlockSize;
}
@Override
public Key getPublicKey(byte[] publicKey) {
if (ValidParam.isNull(getPublicKey()) && !ValidParam.isEmpty(publicKey)) {
this.publicKey = (PublicKey) getPublicKey(new X509EncodedKeySpec(publicKey));
}
return this.publicKey;
}
@Override
public Key getPrivateKey(byte[] privateKey) {
if (ValidParam.isNull(getPrivateKey()) && !ValidParam.isEmpty(privateKey)) {
this.privateKey = (PrivateKey) getPrivateKey(new PKCS8EncodedKeySpec(privateKey));
}
return this.privateKey;
}
@Override
public Key getPublicKey(KeySpec publicKey) {
if (ValidParam.isNull(getPublicKey())) {
this.publicKey = KeyUtils.generatePublicKey(getAlgorithm(), getProvider(), publicKey);
}
return this.publicKey;
}
@Override
public Key getPrivateKey(KeySpec privateKey) {
if (ValidParam.isNull(getPrivateKey())) {
this.privateKey = KeyUtils.generatePrivateKey(getAlgorithm(), getProvider(), privateKey);
}
return this.privateKey;
}
@Override
public Provider getProvider() {
return provider;
}
@Override
public Key generateKey(byte[] publicKey, byte[] privateKey, CipherMode cipherMode) {
return ChooseOr.create(Eq.enums(CipherMode.ENCRYPT, cipherMode), () -> getPublicKey(publicKey))
.orElse(() -> getPrivateKey(privateKey));
}
@Override
public Key generateKey(KeySpec publicKey, KeySpec privateKey, CipherMode cipherMode) {
return ChooseOr.create(Eq.enums(CipherMode.ENCRYPT, cipherMode), () -> getPublicKey(publicKey))
.orElse(() -> getPrivateKey(privateKey));
}
/**
* 获取公共指数
*
* @author Pan
* @return BigInteger
*/
public BigInteger getModulus() {
if (ValidParam.isNotNull(this.publicKey)) {
return ((BCRSAPublicKey) this.publicKey).getModulus();
}
if (ValidParam.isNotNull(this.privateKey)) {
return ((BCRSAPrivateKey) this.privateKey).getModulus();
}
return null;
}
/**
* 获取公钥特征值
*
* @author Pan
* @return BigInteger
*/
public BigInteger getPublicExponent() {
return this.publicKey == null ? null : ((BCRSAPublicKey) this.publicKey).getPublicExponent();
}
/**
* 获取私钥特征值
*
* @author Pan
* @return BigInteger
*/
public BigInteger getPrivateExponent() {
return this.privateKey == null ? null : ((BCRSAPrivateKey) this.privateKey).getPrivateExponent();
}
@Override
public byte[] getPublicEncode() {
return this.publicKey == null ? Empty.arrayByte() : getPublicKey().getEncoded();
}
@Override
public String getPublicEncodeToHex() {
byte[] publicEncode = getPublicEncode();
return publicEncode == null ? null : HexUtils.encode(publicEncode);
}
@Override
public byte[] getPublicEncodeToBase64() {
byte[] publicEncode = getPublicEncode();
return publicEncode == null ? Empty.arrayByte() : Base64Utils.encode(publicEncode);
}
@Override
public String getPublicEncodeToBase64Str() {
byte[] publicEncode = getPublicEncode();
return publicEncode == null ? null : Base64Utils.encodeToStr(publicEncode);
}
@Override
public byte[] getPrivateEncode() {
return this.privateKey == null ? Empty.arrayByte() : getPrivateKey().getEncoded();
}
@Override
public String getPrivateEncodeToHex() {
return KeyUtils.encode(getPrivateEncode());
}
@Override
public byte[] getPrivateEncodeToBase64() {
byte[] privateEncode = getPrivateEncode();
return privateEncode == null ? Empty.arrayByte() : Base64Utils.encode(privateEncode);
}
@Override
public String getPrivateEncodeToBase64Str() {
byte[] privateEncode = getPrivateEncode();
return privateEncode == null ? null : Base64Utils.encodeToStr(privateEncode);
}
/**
* 创建Key密钥对对象(可用于缓存)
* 默认十六进制编码格式
*
* @author Pan
* @return AsymmetricKey
*/
public AsymmetricKey createKeyObject() {
return createKeyObject(true);
}
/**
* 创建Key密钥对对象(可用于缓存)
* 自定义编码格式(true十六进制, false Base64)
*
* @author Pan
* @param isHex true十六进制, false Base64
* @return AsymmetricKey
*/
public AsymmetricKey createKeyObject(boolean isHex) {
return new AsymmetricKey(getPublicEncode(), getPrivateEncode(), isHex);
}
}