目录
- 一、SM2国密加解密算法
- 1.1、pom文件引入依赖包
- 1.2、SM2加解密工具类
- 1.3、测试类
一、SM2国密加解密算法
1.1、pom文件引入依赖包
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk18on</artifactId>
<version>1.72</version>
</dependency>
1.2、SM2加解密工具类
-
SM2加解密工具类
package com.xz.utils; import org.bouncycastle.asn1.gm.GMNamedCurves; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.crypto.engines.SM2Engine; import org.bouncycastle.crypto.params.*; 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.ECPoint; import org.bouncycastle.util.encoders.Hex; import java.math.BigInteger; import java.security.*; import java.security.spec.ECGenParameterSpec; import java.util.HashMap; import java.util.Map; /** * 适用于前后端公用的SM2秘钥生成、加解密工具类 */ public class SimpSM2Util { /** * 公钥常量 */ public static final String KEY_PUBLIC_KEY = "publicKey"; /** * 私钥返回值常量 */ public static final String KEY_PRIVATE_KEY = "privateKey"; /** * SM2加密算法 * @param publicKey 公钥 * @param data 明文数据 * @return */ public static String encrypt(String publicKey, String data) { // 获取一条SM2曲线参数 X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1"); // 构造ECC算法参数,曲线方程、椭圆曲线G点、大整数N 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.Mode.C1C3C2); // 设置sm2为加密模式 sm2Engine.init(true, new ParametersWithRandom(publicKeyParameters, new SecureRandom())); byte[] arrayOfBytes = null; try { byte[] in = data.getBytes(); arrayOfBytes = sm2Engine.processBlock(in, 0, in.length); } catch (Exception e) { System.out.println("SM2加密时出现异常:"+e.getMessage()); } return Hex.toHexString(arrayOfBytes); } /** * SM2解密算法 * @param privateKey 私钥 * @param cipherData 密文数据 * @return */ public static String decrypt(String privateKey, String cipherData) { // 使用BC库加解密时密文以04开头,传入的密文前面没有04则补上 if (!cipherData.startsWith("04")){ cipherData = "04" + cipherData; } byte[] cipherDataByte = Hex.decode(cipherData); BigInteger privateKeyD = new BigInteger(privateKey, 16); //获取一条SM2曲线参数 X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1"); //构造domain参数 ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(), sm2ECParameters.getG(), sm2ECParameters.getN()); ECPrivateKeyParameters privateKeyParameters = new ECPrivateKeyParameters(privateKeyD, domainParameters); SM2Engine sm2Engine = new SM2Engine(SM2Engine.Mode.C1C3C2); // 设置sm2为解密模式 sm2Engine.init(false, privateKeyParameters); String result = ""; try { byte[] arrayOfBytes = sm2Engine.processBlock(cipherDataByte, 0, cipherDataByte.length); return new String(arrayOfBytes); } catch (Exception e) { System.out.println("SM2解密时出现异常:"+e.getMessage()); } return result; } /** * 生成密钥 */ public static Map<String, String> createKey() throws Exception{ ECGenParameterSpec sm2Spec = new ECGenParameterSpec("sm2p256v1"); // 获取一个椭圆曲线类型的密钥对生成器 KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", new BouncyCastleProvider()); // 使用SM2参数初始化生成器 kpg.initialize(sm2Spec); // 获取密钥对 KeyPair keyPair = kpg.generateKeyPair(); PublicKey publicKey = keyPair.getPublic(); BCECPublicKey p=(BCECPublicKey)publicKey; System.out.println("publicKey:"+Hex.toHexString(p.getQ().getEncoded(false))); PrivateKey privateKey = keyPair.getPrivate(); BCECPrivateKey s=(BCECPrivateKey)privateKey; System.out.println("privateKey:"+Hex.toHexString(s.getD().toByteArray())); Map<String, String> result = new HashMap<>(); result.put(KEY_PUBLIC_KEY, Hex.toHexString(p.getQ().getEncoded(false))); result.put(KEY_PRIVATE_KEY, Hex.toHexString(s.getD().toByteArray())); return result; } }
1.3、测试类
-
测试类
public static void main(String[] args) throws Exception { Map<String, String> key = createKey(); String publicKey = key.get(KEY_PUBLIC_KEY); System.out.println("公钥:"+publicKey); String privateKey = key.get(KEY_PRIVATE_KEY); System.out.println("私钥:"+privateKey); String str="hello java123456"; System.out.println("加密前结果:"+str); String encrypt = encrypt(publicKey, str); System.out.println("加密后结果:"+encrypt); String decrypt = decrypt(privateKey, encrypt); System.out.println("解密后结果:"+decrypt); }
-
测试结果,如下图所示: