需要使用SM2进行加解密,百度查询的都是自己生成密钥对,然后进行加解密。现在密钥对已给,需要构造加解密公私钥对象进行加解密操作。最后找到hutool工具包直接可以根据公私钥进行构造一SM2对象。查看源码研究了下翻译一下使用bouncycastle包进行实现大致如下这样
添加依赖包
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.65</version>
</dependency>
根据现有公私钥信息进行加密解密
import org.bouncycastle.asn1.gm.GMNamedCurves;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.Digest;
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.crypto.params.ParametersWithRandom;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.util.BigIntegers;
import org.bouncycastle.util.encoders.Hex;
public class SM2Test {
static String SM2_CURVE_NAME = "sm2p256v1";
public static void main(String[] args) throws Exception {
//私钥
String prvKey = "23be18173850ac04c5255984759e15bf60a8eb0f54880b01a9bc24e20e82df48";
//公钥坐标
String x = "741192ca3ee1a2ba9a50ccab30dd069b29437e2f38fcba709bf84f8a3e732584";
String y = "a47f526415387d5eeb48257fa6e4a5603c7b2ba729ede7c61dfe109d89bd02b1";
String info = "中国";
byte[] data = info.getBytes();
SM2Test sm2 = new SM2Test();
//KeyPair keyPair = sm2.genKeyPair();
ECDomainParameters domain = sm2.getDomain();
SM2Engine engine = sm2.getSM2Engine();
//公钥加密
CipherParameters pubKeyParameters = sm2.getPubKey(x, y, domain);
engine.init(true, pubKeyParameters);
byte[] encData = engine.processBlock(data, 0, data.length);
System.out.println("加密后内容:"+Hex.toHexString(encData));
//私钥解密
CipherParameters PrivateKey = sm2.getPrvKey(prvKey,domain);
engine.init(false, PrivateKey);
byte[] decData = engine.processBlock(encData, 0, encData.length);
System.out.println("解密后内容:"+new String(decData));
}
/**
* 构造私钥对象
* @param prvKey
* @return
*/
public CipherParameters getPrvKey(String prvKey,ECDomainParameters domain) {
BigInteger prvKeyData = BigIntegers.fromUnsignedByteArray(Hex.decode(prvKey));
ECPrivateKeyParameters PrivateKey = new ECPrivateKeyParameters(prvKeyData, domain);
return PrivateKey;
}
/**
* 构造公钥对象
* @param x
* @param y
* @param domain
* @return
*/
public CipherParameters getPubKey(String x,String y,ECDomainParameters domain) {
ECCurve curve = domain.getCurve();
ECPoint point = curve.createPoint(BigIntegers.fromUnsignedByteArray(Hex.decode(x)), BigIntegers.fromUnsignedByteArray(Hex.decode(y)));
ECPublicKeyParameters PublicKey = new ECPublicKeyParameters(point, domain);
CipherParameters pubKeyParameters = new ParametersWithRandom(PublicKey);
return pubKeyParameters;
}
public SM2Engine getSM2Engine() {
Digest digest = new SM3Digest();
SM2Engine engine = new SM2Engine(digest,SM2Engine.Mode.C1C3C2);
return engine;
}
public ECDomainParameters getDomain() {
X9ECParameters x9ECParameters= GMNamedCurves.getByName(SM2_CURVE_NAME);
ECDomainParameters domain = new ECDomainParameters(
x9ECParameters.getCurve(),
x9ECParameters.getG(),
x9ECParameters.getN(),
x9ECParameters.getH()
);
return domain;
}
/**
* 生成密钥对
* @return
* @throws Exception
*/
public KeyPair genKeyPair() throws Exception {
final ECGenParameterSpec sm2Spec = new ECGenParameterSpec(SM2_CURVE_NAME);
// 获取一个椭圆曲线类型的密钥对生成器
final KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", new BouncyCastleProvider());
SecureRandom random = new SecureRandom();
// 使用SM2的算法区域初始化密钥生成器
kpg.initialize(sm2Spec, random);
// 获取密钥对
KeyPair keyPair = kpg.generateKeyPair();
BCECPublicKey pubk = (BCECPublicKey) keyPair.getPublic();
BCECPrivateKey privK = (BCECPrivateKey) keyPair.getPrivate();
byte[] privData = BigIntegers.asUnsignedByteArray(32,privK.getD());
byte[] pubx = BigIntegers.asUnsignedByteArray(32, pubk.getQ().getRawXCoord().toBigInteger());
byte[] puby = BigIntegers.asUnsignedByteArray(32, pubk.getQ().getRawYCoord().toBigInteger());
System.out.println("Private Key:"+Hex.toHexString(privData));
System.out.println("PUB X:"+Hex.toHexString(pubx));
System.out.println("PUB Y:"+Hex.toHexString(puby));
return keyPair;
}