引用jar包
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.60</version>
</dependency>
工具类
package com.waving.test;
import org.bouncycastle.asn1.gm.GMNamedCurves;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.engines.SM2Engine;
import org.bouncycastle.crypto.generators.ECKeyPairGenerator;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECKeyGenerationParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.math.ec.ECPoint;
import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.Base64;
public class SM2Main {
public static void main(String[] args) throws Exception{
String password = "04068521d007785e02a02f4d51eab175040f371a69ee8f14ec41418d05dc533c0ba15305006011ae2a9524c0c684f1b2e332087c43af4d52986770047cfc204e302f62b91559708556b5afe45c5cd66db76877b536ca070020334ea5519eefe5718f77e016e06ec50e27d0089be3b41335aef50338";
String privateKey = "5206da9df203603af3d4aa25f6b6df08dfa636249609407f6ea8d069d9e2dc2b";
String result = getPassword(password, privateKey);
System.out.println("result = " + result);
//generatePublicKey();
}
public static String generatePublicKey() throws Exception {
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);
System.out.println("privateKeyHex = " + privateKeyHex);
//公钥,16进制格式,由后端生成
ECPoint ecPoint = ((ECPublicKeyParameters) asymmetricCipherKeyPair.getPublic()).getQ();
String publicKeyHex = org.bouncycastle.util.encoders.Hex.toHexString(ecPoint.getEncoded(false));
System.out.println("publicKeyHex = " + publicKeyHex);
return publicKeyHex;
}
public static String getPassword(String password, String privateKey) {
String data = null;
try {
BigInteger privateKeyD = new BigInteger(privateKey, 16);
byte[] cipherDataByte = org.bouncycastle.util.encoders.Hex.decode(password);
X9ECParameters sm2EcParameters = GMNamedCurves.getByName("sm2p256v1");
ECDomainParameters domainParameters = new ECDomainParameters(sm2EcParameters.getCurve(), sm2EcParameters.getG(), sm2EcParameters.getN());
ECPrivateKeyParameters privateKeyParameters = new ECPrivateKeyParameters(privateKeyD, domainParameters);
// 用私钥解密
SM2Engine sm2Engine = new SM2Engine();
sm2Engine.init(false, privateKeyParameters);
byte[] arrayOfBytes = Base64.getDecoder().decode(sm2Engine.processBlock(cipherDataByte, 0, cipherDataByte.length));
java.lang.String s = new java.lang.String(arrayOfBytes);
data = new String(s);
} catch (InvalidCipherTextException e) {
e.printStackTrace();
}
return data;
}
}
前端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>sm2测试</title>
<script src="js/crypto-js.js"></script>
<script src="js/sm2.js"></script>
<script>
function encrypt() {
// 公钥
var publicKey = "042528117c8b05f06b1a9da658811e169156801d23b77792b6e461de327157bf5a0c1477ad266883b99be6ec049a51b141fa94864d87b9c8724d86f5247f26b298";
var encrypt = sm2Encrypt("waving is best", publicKey, 0);
console.log(encrypt);
}
</script>
</head>
<body onload="encrypt()">
<button onload="encrypt()">haha</button>
</body>
</html>
主要的是要这个sm2.js文件,可去gitHub这个项目里下载这个js,附https://github.com/biparadox/gm_sm2_master
附注
sm2加密算法为非对称加密算法,它会生成公钥与私钥,私钥保存在后台配置文件中,前端拿着私钥对数据进行加密,然后传给后端,后端将加密数据保存在数据库,当真实想要的时候再进行解密