赞
踩
引入依赖
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.69</version>
</dependency>
公钥是对接方给的,是一个长字符串类似于这种格式
工具类中也有生成公私钥的方法,我测试加解密也能成功
秘钥生成借鉴的是这个文章的内容
https://blog.csdn.net/Kevin_zhai/article/details/109351247
加解密的方法初版忘了是在哪借鉴的了见谅,初版是直接用PublicKey 和 PrivateKey 对象加解密的,我把它改为用字符串转为公钥和私钥的方式加解密。
加密方法因为需求是要返回加密后的base64字符串,本来是直接转为字符串返回的,后来又改为这样的,同样的解密的时候也改了先用base64解码,根据需求自己调一下吧。
package com.encrypt.utils.sm2; import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.binary.Base64; import org.bouncycastle.crypto.engines.SM2Engine; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.params.ParametersWithRandom; 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.jce.spec.ECParameterSpec; import sun.misc.BASE64Decoder; import java.security.*; import java.security.spec.ECGenParameterSpec; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; /** * @ClassName SM2Util * @Description //TODO * @Date 2022/2/18 * @Author yangy * @Version 1.0 **/ @Slf4j public class SM2Util { /** * SM2加密算法 * @param publicKeyStr 公钥 * @param data 明文数据 * @return */ public static String encrypt(String publicKeyStr, String data){ Security.addProvider(new BouncyCastleProvider()); PublicKey publicKey = null; try { log.info("开始转换字符串公钥,公钥值:{},数据值:{}",publicKeyStr,data); byte[] keyBytes; keyBytes = (new BASE64Decoder()).decodeBuffer(publicKeyStr); KeyFactory keyFactory = KeyFactory.getInstance("EC", BouncyCastleProvider.PROVIDER_NAME); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); publicKey = keyFactory.generatePublic(keySpec); log.info("转换后的公钥:{}",publicKey); } catch (Exception e) { log.error("SM2字符串公钥转换异常:{}",e.getMessage()); e.printStackTrace(); } log.info("SM2开始加密数据"); ECPublicKeyParameters ecPublicKeyParameters = null; if (publicKey instanceof BCECPublicKey) { BCECPublicKey bcecPublicKey = (BCECPublicKey) publicKey; ECParameterSpec ecParameterSpec = bcecPublicKey.getParameters(); ECDomainParameters ecDomainParameters = new ECDomainParameters(ecParameterSpec.getCurve(), ecParameterSpec.getG(), ecParameterSpec.getN()); ecPublicKeyParameters = new ECPublicKeyParameters(bcecPublicKey.getQ(), ecDomainParameters); } SM2Engine sm2Engine = new SM2Engine(); sm2Engine.init(true, new ParametersWithRandom(ecPublicKeyParameters, 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.getMessage()); System.out.println("SM2加密时出现异常:"); } return Base64.encodeBase64String(arrayOfBytes); } /** * SM2解密算法 * @param privateKeyStr 私钥 * @param cipherData 密文数据 * @return */ public static String decrypt(String privateKeyStr, String cipherData){ PrivateKey privateKey = null; byte[] keyBytes; try { keyBytes = (new BASE64Decoder()).decodeBuffer(privateKeyStr); KeyFactory keyFactory = KeyFactory.getInstance("EC", BouncyCastleProvider.PROVIDER_NAME); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes); privateKey=keyFactory.generatePrivate(keySpec); }catch (Exception e){ log.error("SM2字符串私钥转换异常:{}",e.getMessage()); e.printStackTrace(); } BCECPrivateKey bcecPrivateKey = (BCECPrivateKey) privateKey; ECParameterSpec ecParameterSpec = bcecPrivateKey.getParameters(); ECDomainParameters ecDomainParameters = new ECDomainParameters(ecParameterSpec.getCurve(), ecParameterSpec.getG(), ecParameterSpec.getN()); ECPrivateKeyParameters ecPrivateKeyParameters = new ECPrivateKeyParameters(bcecPrivateKey.getD(), ecDomainParameters); SM2Engine sm2Engine = new SM2Engine(); sm2Engine.init(false, ecPrivateKeyParameters); String result = null; byte[] arrayOfBytes = null; try { byte[] in = Base64.decodeBase64(cipherData); arrayOfBytes = sm2Engine.processBlock(in,0, in.length); result=new String(arrayOfBytes, "utf-8"); } catch (Exception e) { System.out.println("SM2解密时出现异常"); } return result; } /** * SM2算法生成密钥对 * @return 密钥对信息 */ public static KeyPair generateSm2KeyPair() { try { final ECGenParameterSpec sm2Spec = new ECGenParameterSpec("sm2p256v1"); // 获取一个椭圆曲线类型的密钥对生成器 final KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", new BouncyCastleProvider()); SecureRandom random = new SecureRandom(); // 使用SM2的算法区域初始化密钥生成器 kpg.initialize(sm2Spec, random); // 获取密钥对 KeyPair keyPair = kpg.generateKeyPair(); return keyPair; } catch (Exception e) { log.error("generate sm2 key pair failed:{}", e.getMessage(), e); return null; } } } /** * main 方法测试 **/ public static void main(String[] args) { KeyPair keyPair = SM2Util.generateSm2KeyPair(); String privateKey = Base64.encodeBase64String(keyPair.getPrivate().getEncoded()); String publicKey = Base64.encodeBase64String(keyPair.getPublic().getEncoded()); System.out.println("公钥:"+publicKey); System.out.println("私钥:"+privateKey); String data="123456"; String encrypt = SM2Util.encrypt(publicKey,data); String decrypt = SM2Util.decrypt(privateKey, encrypt); System.out.println("加密后数据:"+encrypt); System.out.println("解密后数据:"+decrypt); }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。