import com.alibaba.fastjson.JSON;
import com.zs.common.core.domain.entity.SysUser;
import org.bouncycastle.asn1.gm.GMNamedCurves;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.engines.SM2Engine;
import org.bouncycastle.crypto.generators.ECKeyPairGenerator;
import org.bouncycastle.crypto.params.*;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.util.encoders.Hex;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.math.BigInteger;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
public class SM2Utils {
private static final Logger log = LoggerFactory.getLogger(SM2Utils.class);
public static String staticPublicKey = "0408fda0c0f6d1e51289cd5edcef7386a696e1a63659dd4ae3516cfd4d0a5dfaa341ff9c86f2572cae9e1406a036d43b71862e8acf0dbfaeb6216c775038b46d40";
public static String staticPrivateKey = "2158c2678f7ee7685392ddc31916b8c835a98887040bbf69f76fa4aa0acff42e";
/**
* 生成SM2公私鑰對
*
* @return
*/
private static void getSM2Key() {
//獲取一條SM2曲線參數
X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");
//構造domain參數
ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(),
sm2ECParameters.getG(), sm2ECParameters.getN());
//1.創建密鑰生成器
ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator();
//2.初始化生成器,帶上隨機數
try {
keyPairGenerator.init(new ECKeyGenerationParameters(domainParameters, SecureRandom.getInstance("SHA1PRNG")));
} catch (NoSuchAlgorithmException e) {
log.error("生成公私鑰對時出現異常:", e);
// e.printStackTrace();
}
//3.生成密鑰對
AsymmetricCipherKeyPair asymmetricCipherKeyPair = keyPairGenerator.generateKeyPair();
ECPoint ecPoint = ((ECPublicKeyParameters) asymmetricCipherKeyPair.getPublic()).getQ();
String publicKey = Hex.toHexString(ecPoint.getEncoded(false));
System.out.println("公鑰:" + publicKey);
BigInteger privatekey = ((ECPrivateKeyParameters) asymmetricCipherKeyPair.getPrivate()).getD();
String priKey = privatekey.toString(16);
System.out.println("私鑰:" + priKey);
}
/**
* SM2加密算法
*
* @param publicKey 公鑰
* @param data 數據
* @return
*/
public static String encrypt(String publicKey, String data) {
// 獲取一條SM2曲線參數
X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");
// 構造domain參數
ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(),
sm2ECParameters.getG(),
sm2ECParameters.getN());
//提取公鑰點
ECPoint pukPoint = sm2ECParameters.getCurve().decodePoint(Hex.decode(publicKey));
// 公鑰前面的02或者03表示是壓縮公鑰,04表示未壓縮公鑰, 04的時候,可以去掉前面的04
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("utf-8");
arrayOfBytes = sm2Engine.processBlock(in, 0, in.length);
} catch (Exception e) {
log.error("SM2加密時出現異常:", e);
}
return Hex.toHexString(arrayOfBytes);
}
/**
* SM2解密算法
*
* @param privateKey 私鑰
* @param cipherData 密文數據
* @return
*/
public static String decrypt(String privateKey, String cipherData) {
byte[] cipherDataByte = Hex.decode(cipherData);
//獲取一條SM2曲線參數
X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");
//構造domain參數
ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(),
sm2ECParameters.getG(), sm2ECParameters.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 = sm2Engine.processBlock(cipherDataByte, 0, cipherDataByte.length);
return new String(arrayOfBytes, "utf-8");
} catch (Exception e) {
log.error("SM2解密時出現異常:", e);
}
return result;
}
/**
* 加密:返回加密串
* @param message
* @return
*/
public static String encryptionMessage(String message){
//加密
String resultPublic = encrypt(staticPublicKey, message);
return resultPublic;
}
/**
* 解析加密串返回解析內容
* @param encrypted
* @return
*/
public static String analysisMessage(String encrypted){
//解密
String resultPrivate = decrypt(staticPrivateKey, encrypted);
return resultPrivate;
}
public static void main(String[] args) {
//生成公私鑰匙對
// getSM2Key();
SysUser su = new SysUser();
su.setUserName("ll123456789");
su.setPassword("ll123456789");
su.setCreateTime(DateUtils.getNowDate());
String message = JSON.toJSONString(su);
//加密
String resultPublic = encryptionMessage(message);
System.out.println("加密結果:" + resultPublic);
//解密
String resultPrivate = analysisMessage(resultPublic);
System.out.println("解密結果:" + resultPrivate);
}
}
<!--國密-->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>1.65</version>
</dependency>