创建秘钥对
//生成随机秘钥对
public static SM2KeyPairVO generateKeyPair() {
try {
X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");
ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(), sm2ECParameters.getG(), sm2ECParameters.getN());
ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator();
keyPairGenerator.init(new ECKeyGenerationParameters(domainParameters, SecureRandom.getInstance("SHA1PRNG")));
AsymmetricCipherKeyPair asymmetricCipherKeyPair = keyPairGenerator.generateKeyPair();
//私钥,16进制格式,自己保存,格式如a2081b5b81fbea0b6b973a3ab6dbbbc65b1164488bf22d8ae2ff0b8260f64853
BigInteger privatekey = ((ECPrivateKeyParameters) asymmetricCipherKeyPair.getPrivate()).getD();
String privateKeyHex = privatekey.toString(16);
//公钥,16进制格式,发给前端,格式如04813d4d97ad31bd9d18d785f337f683233099d5abed09cb397152d50ac28cc0ba43711960e811d90453db5f5a9518d660858a8d0c57e359a8bf83427760ebcbba
ECPoint ecPoint = ((ECPublicKeyParameters) asymmetricCipherKeyPair.getPublic()).getQ();
String publicKeyHex = Hex.toHexString(ecPoint.getEncoded(false));
SM2KeyPairVO sm2KeyPairVO = new SM2KeyPairVO();
sm2KeyPairVO.setPrivateKey(privateKeyHex);
sm2KeyPairVO.setPublicKey(publicKeyHex);
return sm2KeyPairVO;
} catch (Exception e) {
log.error("SM2密钥对生成失败失败,原因是:" + e.getMessage());
}
return null;
}
加密
/**
* SM2加密算法
* @param publicKey 公钥
* @param data 数据
* @return
*/
public static String encrypt(String publicKey,String data){
//获取一条曲线参数
X9ECParameters sm2ECParam = GMNamedCurves.getByName("sm2p256v1");
ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParam.getCurve(), sm2ECParam.getG(), sm2ECParam.getN());
//提取公钥点
ECPoint pukPoint = sm2ECParam.getCurve().decodePoint(Hex.decode(publicKey));
//公钥值
ECPublicKeyParameters publicKeyParameters = new ECPublicKeyParameters(pukPoint, domainParameters);
//做加签
SM2Engine sm2Engine = new SM2Engine();
sm2Engine.init(true,new ParametersWithRandom(publicKeyParameters,new SecureRandom()));
byte[] arrayOfBytes = null;
try{
byte[] in = data.getBytes(Constants.CHARSET_UTF8);
arrayOfBytes = sm2Engine.processBlock(in,0,in.length);
} catch (Exception e) {
log.error("SM2加密失败");
}
return Hex.toHexString(arrayOfBytes);
}
解密
/**
* SM2解密算法
* @param privateKey 私钥
* @param CipherData 密文数据
* @return
*/
public static String decryptSM2(String privateKey,String CipherData){
byte[] cipherDateByte = Hex.decode(CipherData);
//获取一条曲线参数
X9ECParameters sm2ECParam = GMNamedCurves.getByName("sm2p256v1");
//构造domain参数
ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParam.getCurve(), sm2ECParam.getG(), sm2ECParam.getN());
BigInteger privateKeyD = new BigInteger(privateKey, 16);
ECPrivateKeyParameters privateKeyParameters = new ECPrivateKeyParameters(privateKeyD, domainParameters);
//做解签
SM2Engine sm2Engine = new SM2Engine();
sm2Engine.init(false,privateKeyParameters);
String result = null;
try{
byte[] arrayOfBytes = Base64.decode(sm2Engine.processBlock(cipherDateByte, 0, cipherDateByte.length));
return new String(arrayOfBytes,Constants.CHARSET_UTF8);
} catch (Exception e) {
log.error("SM2解密失败");
}
return result;
}
MAIN函数测试
public static void main(String[] args) {
SM2KeyPairVO sm2KeyPairVO = generateKeyPair();
String pKey = sm2KeyPairVO.getPublicKey();
String priKey = sm2KeyPairVO.getPrivateKey();
System.out.println("公钥为: " + pKey);
System.out.println("私钥为: " + priKey);
String publicKey = pKey;
String privateKey = priKey;
String content = "hello";
String encrypt = encrypt(publicKey, Base64.toBase64String(content.getBytes(StandardCharsets.UTF_8)));
System.out.println("密文:" + encrypt);
String test = decryptSM2(privateKey, encrypt);
System.out.println("解密:" + test);
}