-
Notifications
You must be signed in to change notification settings - Fork 1
Open
Description
博主你好,以下是使用BC库SM2加解密大数据的一种方式,看看有没有参考价值
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.crypto.engines.SM2Engine;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.util.encoders.Hex;
import java.math.BigInteger;
import java.security.Security;
import java.util.Arrays;
public class SM2EncryptUtil {
static {
// 添加 Bouncy Castle 提供商
if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
Security.addProvider(new BouncyCastleProvider());
}
}
// SM2 曲线参数(国密标准)
private static final ECCurve curve = new ECCurve.Fp(
new BigInteger("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", 16),
new BigInteger("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC", 16),
new BigInteger("28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93", 16)
);
private static final ECPoint G = curve.decodePoint(Hex.decode("04"
+ "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7"
+ "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0"));
private static final BigInteger n = new BigInteger("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123", 16);
private static final ECDomainParameters domainParams = new ECDomainParameters(curve, G, n);
/**
* SM2 加密(支持大数据分块)
*
* @param data json明文数据
* @param publicKey 公钥(Hex 格式)
* @return 加密后的数据(Hex 格式)
*/
public static String sm2Encrypt(String data, String publicKey) throws InvalidCipherTextException {
byte[] dataBytes = data.getBytes();
// SM2 单次最大加密块大小
/* int blockSize = 254;
StringBuilder result = new StringBuilder();
for (int i = 0; i < dataBytes.length; i += blockSize) {
int length = Math.min(blockSize, dataBytes.length - i);
byte[] block = Arrays.copyOfRange(dataBytes, i, i + length);
String encryptedBlock = sm2EncryptBlock(block, publicKey);
result.append(encryptedBlock);
}*/
// 添加 04 前缀表示未压缩格式
return "04" + sm2EncryptBlock(dataBytes, publicKey);
}
/**
* SM2 单块加密
*
* @param data 数据块
* @param publicKey 公钥(Hex 格式)
* @return 加密后的数据(Hex 格式)
*/
private static String sm2EncryptBlock(byte[] data, String publicKey) throws InvalidCipherTextException {
ECPoint pubPoint = curve.decodePoint(Hex.decode(publicKey));
ECPublicKeyParameters pubKeyParams = new ECPublicKeyParameters(pubPoint, domainParams);
SM2Engine engine = new SM2Engine(SM2Engine.Mode.C1C3C2);
engine.init(true, pubKeyParams);
byte[] encrypted = engine.processBlock(data, 0, data.length);
// 添加 04 前缀表示未压缩格式
return "04" + Hex.toHexString(encrypted);
}
/**
* SM2 解密(支持大数据分块)
*
* @param encryptedData 加密数据(Hex 格式)
* @param privateKey 私钥(Hex 格式)
* @return 解密后的明文数据
*/
public static String sm2Decrypt(String encryptedData, String privateKey) throws InvalidCipherTextException {
// 04 前缀表示未压缩格式,解密的时候不能去掉,否则无法解析出C1曲线点
/* if (encryptedData.startsWith("04")) {
// 去除 04 前缀
encryptedData = encryptedData.substring(2);
}*/
byte[] encryptedBytes = Hex.decode(encryptedData);
// SM2 密文固定长度(C1+C3+C2)
return sm2DecryptBlock(encryptedBytes, privateKey);
}
/**
* SM2 单块解密
*
* @param encryptedData 加密数据块
* @param privateKey 私钥(Hex 格式)
* @return 解密后的数据
*/
private static String sm2DecryptBlock(byte[] encryptedData, String privateKey) throws InvalidCipherTextException {
BigInteger d = new BigInteger(privateKey, 16);
ECPrivateKeyParameters privKeyParams = new ECPrivateKeyParameters(d, domainParams);
SM2Engine engine = new SM2Engine(SM2Engine.Mode.C1C3C2);
engine.init(false, privKeyParams);
byte[] decrypted = engine.processBlock(encryptedData, 0, encryptedData.length);
return Hex.toHexString(decrypted);
}
/**
* SM3 摘要计算
*
* @param data 输入数据
* @return 摘要结果(Hex 格式)
*/
public static String sm3Digest(byte[] data) {
SM3Digest digest = new SM3Digest();
digest.update(data, 0, data.length);
byte[] hash = new byte[digest.getDigestSize()];
digest.doFinal(hash, 0);
return Hex.toHexString(hash).toLowerCase();
}
}
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels