使用hutool工具类国密算法SM2实现
首先引入maven
<dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15to18</artifactId><version>1.69</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.4.1</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.10</version></dependency>
直接上代码
importlombok.Data;/**
* 1. @description:
* 2. @author: xh
* 3. @time: 2022/7/14
*/@DatapublicclassSMKeyPair{//私钥privateString priKey;//公钥privateString pubKey;publicSMKeyPair(String priKey,String pubKey){this.priKey = priKey;this.pubKey = pubKey;}}
importcn.hutool.core.util.HexUtil;importcn.hutool.core.util.StrUtil;importcn.hutool.crypto.BCUtil;importcn.hutool.crypto.SmUtil;importcn.hutool.crypto.asymmetric.KeyType;importcn.hutool.crypto.asymmetric.SM2;importorg.bouncycastle.crypto.params.ECPrivateKeyParameters;importorg.bouncycastle.crypto.params.ECPublicKeyParameters;importjava.security.PrivateKey;importjava.security.PublicKey;/**
* 1. @description: 国密SM2加解密
* 2. @author: xh
* 3. @time: 2022/7/14
*/publicclassSm2Utils{/**
* 生成公私钥对(默认压缩公钥)
* @return
*/publicstaticSMKeyPairgenKeyPair(){SM2 sm2 =SmUtil.sm2();//这里会自动生成对应的随机秘钥对byte[] privateKey =BCUtil.encodeECPrivateKey(sm2.getPrivateKey());//这里默认公钥压缩 公钥的第一个字节用于表示是否压缩 02或者03表示是压缩公钥,04表示未压缩公钥byte[] publicKey =BCUtil.encodeECPublicKey(sm2.getPublicKey());//这里得到未压缩的公钥 byte[] publicKey = ((BCECPublicKey) sm2.getPublicKey()).getQ().getEncoded(false);String priKey =HexUtil.encodeHexStr(privateKey);String pubKey =HexUtil.encodeHexStr(publicKey);returnnewSMKeyPair(priKey, pubKey);}/**
* SM2加密算法
* @param publicKey 公钥
* @param text 数据
* @return
*/publicstaticStringencrypt(String publicKey,String text){ECPublicKeyParameters ecPublicKeyParameters =null;//这里需要根据公钥的长度进行加工if(publicKey.length()==130){//这里需要去掉开始第一个字节 第一个字节表示标记
publicKey = publicKey.substring(2);String xhex = publicKey.substring(0,64);String yhex = publicKey.substring(64,128);
ecPublicKeyParameters =BCUtil.toSm2Params(xhex, yhex);}else{PublicKey p =BCUtil.decodeECPoint(publicKey,SmUtil.SM2_CURVE_NAME);
ecPublicKeyParameters =BCUtil.toParams(p);}//创建sm2 对象SM2 sm2 =newSM2(null, ecPublicKeyParameters);// 公钥加密return sm2.encryptBcd(text,KeyType.PublicKey);}/**
* SM2加密算法
* @param publicKey 公钥
* @param text 明文数据
* @return
*/publicstaticStringencrypt(PublicKey publicKey,String text){ECPublicKeyParameters ecPublicKeyParameters =BCUtil.toParams(publicKey);//创建sm2 对象SM2 sm2 =newSM2(null, ecPublicKeyParameters);// 公钥加密return sm2.encryptBcd(text,KeyType.PublicKey);}/**
* SM2解密算法
* @param privateKey 私钥
* @param cipherData 密文数据
* @return
*/publicstaticStringdecrypt(String privateKey,String cipherData){ECPrivateKeyParameters ecPrivateKeyParameters =BCUtil.toSm2Params(privateKey);//创建sm2 对象SM2 sm2 =newSM2(ecPrivateKeyParameters,null);// 私钥解密returnStrUtil.utf8Str(sm2.decryptFromBcd(cipherData,KeyType.PrivateKey));}/**
* SM2解密算法
* @param privateKey 私钥
* @param cipherData 密文数据
* @return
*/publicstaticStringdecrypt(PrivateKey privateKey,String cipherData){ECPrivateKeyParameters ecPrivateKeyParameters =BCUtil.toParams(privateKey);//创建sm2 对象SM2 sm2 =newSM2(ecPrivateKeyParameters,null);// 私钥解密returnStrUtil.utf8Str(sm2.decryptFromBcd(cipherData,KeyType.PrivateKey));}/**
* 私钥签名
* @param privateKey 私钥
* @param content 待签名内容
* @return
*/publicstaticStringsign(String privateKey,String content){ECPrivateKeyParameters ecPrivateKeyParameters =BCUtil.toSm2Params(privateKey);//创建sm2 对象SM2 sm2 =newSM2(ecPrivateKeyParameters,null);String sign = sm2.signHex(HexUtil.encodeHexStr(content));return sign;}/**
* 验证签名
* @param publicKey 公钥
* @param content 待签名内容
* @param sign 签名值
* @return
*/publicstaticbooleanverify(String publicKey,String content,String sign){ECPublicKeyParameters ecPublicKeyParameters =null;//这里需要根据公钥的长度进行加工if(publicKey.length()==130){//这里需要去掉开始第一个字节 第一个字节表示标记
publicKey = publicKey.substring(2);String xhex = publicKey.substring(0,64);String yhex = publicKey.substring(64,128);
ecPublicKeyParameters =BCUtil.toSm2Params(xhex, yhex);}else{PublicKey p =BCUtil.decodeECPoint(publicKey,SmUtil.SM2_CURVE_NAME);
ecPublicKeyParameters =BCUtil.toParams(p);}//创建sm2 对象SM2 sm2 =newSM2(null, ecPublicKeyParameters);boolean verify = sm2.verifyHex(HexUtil.encodeHexStr(content), sign);return verify;}publicstaticvoidmain(String[] args){SMKeyPair smKeyPair =genKeyPair();String priKey = smKeyPair.getPriKey();System.out.println("私钥"+ priKey);String pubKey = smKeyPair.getPubKey();System.out.println("公钥"+ pubKey);//明文String text ="123123123";System.out.println("测试明文文本"+ text);//签名测试String sign =sign(priKey, text);System.out.println("生成签名"+ sign);//验签测试boolean verify =verify(pubKey, text, sign);System.out.println("验签结果"+ verify);//加解密测试String encryptData =encrypt(pubKey, text);System.out.println("加密结果"+ encryptData);String decryptData =decrypt(priKey, encryptData);System.out.println("解密结果"+ decryptData);}}
私钥d1197a8dc58791f3d62c28a3447089f98fb9cf46f4a0608b6db9f119b939c16f
公钥035a5f4a04c818e9721ca88783c49ee391e3c4b42422fd7ac83a1abdb6ca5dd546
测试明文文本123123123
生成签名3045022100c87cf39c28e353937540acf14d87451722289098de6fb8ac0e1a33d7082a7daf022031786170b1bde6fbc86f10e3c0a32b428baf5071c18c5c2b1f378ab4fab440c6
验签结果true
加密结果04782AA43A09A3716819B7DE201B962EBE7A48A3471B1963DDAFB723EC20A4F20BECB12201A3A6477E226130E5DB9BF786C9EBA5BC82912D7AE240025318140649F9B364ECC6F61412C561556768D9C2BC7B9CDE264F4B62153711F0991EECAA405982BE5AE2F6D2C3E2
解密结果123123123
本文转载自: https://blog.csdn.net/weixin_42192467/article/details/125785311
版权归原作者 一小昊 所有, 如有侵权,请联系我们删除。
版权归原作者 一小昊 所有, 如有侵权,请联系我们删除。