package com.xxx.tax.util;import lombok.extern.slf4j.Slf4j;import org.apache.commons.lang3.StringUtils;import org.bouncycastle.asn1.gm.GMNamedCurves;import org.bouncycastle.asn1.x9.X9ECParameters;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 org.bouncycastle.jce.spec.ECPrivateKeySpec;import org.bouncycastle.jce.spec.ECPublicKeySpec;import org.bouncycastle.math.ec.ECPoint;import org.bouncycastle.util.encoders.Hex;import javax.crypto.Cipher;import java.math.BigInteger;import java.security.InvalidAlgorithmParameterException;import java.security.KeyFactory;import java.security.KeyPair;import java.security.KeyPairGenerator;import java.security.NoSuchAlgorithmException;import java.security.SecureRandom;import java.security.spec.ECGenParameterSpec;import java.util.Base64;import java.util.HashMap;import java.util.Map;@Slf4jpublic class Sm2Utils { public static Map generateKeyPair() { Map resultMap = new HashMap<>(2); try { BouncyCastleProvider provider = new BouncyCastleProvider(); // 获取椭圆曲线相关生成参数规格 ECGenParameterSpec genParameterSpec = new ECGenParameterSpec("sm2p256v1"); KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC", provider); // 使用SM2的算法区域初始化密钥生成器 keyPairGenerator.initialize(genParameterSpec, new SecureRandom()); // 生成密钥对 KeyPair keyPair = keyPairGenerator.generateKeyPair(); BCECPrivateKey exPrivateKey = (BCECPrivateKey) keyPair.getPrivate(); BCECPublicKey ecPublicKey = (BCECPublicKey) keyPair.getPublic(); // 解密密钥 BigInteger privateKey = exPrivateKey.getD(); // 加密密钥 ECPoint publicKey = ecPublicKey.getQ(); resultMap.put("privateKey", privateKey.toString(16)); resultMap.put("publicKey", new String(Hex.encode(publicKey.getEncoded(true)))); } catch (NoSuchAlgorithmException | InvalidAlgorithmParameterException e) { log.info("NoSuchAlgorithmException | InvalidAlgorithmParameterException {}", e.getMessage(), e); } return resultMap; } public static String printHexString(byte[] b) { StringBuilder builder = new StringBuilder(); for (int i = 0; i < b.length; i++) { String hex = Integer.toHexString(b[i] & 0xFF); if (hex.length() == 1) { builder.append('0'+hex); hex = '0' + hex; }else { builder.append(hex); } //System.out.print(hex.toLowerCase()); } System.out.println(builder.toString()); return builder.toString(); } public static String encrypt(String publicKey, String content) { String contentEncrypt = StringUtils.EMPTY; try { BouncyCastleProvider provider = new BouncyCastleProvider(); // 获取SM2相关参数 X9ECParameters parameters = GMNamedCurves.getByName("sm2p256v1"); // 椭圆曲线参数规格 ECParameterSpec ecParameterSpec = new ECParameterSpec(parameters.getCurve(), parameters.getG(), parameters.getN(), parameters.getH()); // 将公钥HEX字符串转换为椭圆曲线对应的点 ECPoint ecPoint = parameters.getCurve().decodePoint(Hex.decode(publicKey)); // 获取椭圆曲线KEY生成器 KeyFactory keyFactory = KeyFactory.getInstance("EC", provider); // 将椭圆曲线点转为公钥KEY对象 BCECPublicKey bcecPublicKey = (BCECPublicKey) keyFactory.generatePublic(new ECPublicKeySpec(ecPoint, ecParameterSpec)); // 获取SM2加密器 Cipher cipher = Cipher.getInstance("SM2", provider); // 初始化为加密模式 cipher.init(Cipher.ENCRYPT_MODE, bcecPublicKey); // 加密并编码为base64格式 contentEncrypt = Base64.getEncoder().encodeToString(cipher.doFinal(content.getBytes())); } catch (Exception e) { log.info("SM2Utils.encrypt(java.lang.String, java.lang.String) error {}", e.getMessage(), e); } return printHexString(contentEncrypt.getBytes()); //return contentEncrypt; } public static String encrypt(String publicKey, byte[] content) { return encrypt(publicKey, new String(content)); } public static String decrypt(String privateKey, String contentDecrypt) { String content = StringUtils.EMPTY; try { BouncyCastleProvider provider = new BouncyCastleProvider(); // 获取SM2相关参数 X9ECParameters parameters = GMNamedCurves.getByName("sm2p256v1"); // 椭圆曲线参数规格 ECParameterSpec ecParameterSpec = new ECParameterSpec(parameters.getCurve(), parameters.getG(), parameters.getN(), parameters.getH()); // 将私钥HEX字符串转换为X值 BigInteger bigInteger = new BigInteger(privateKey, 16); // 获取椭圆曲线KEY生成器 KeyFactory keyFactory = KeyFactory.getInstance("EC", provider); // 将X值转为私钥KEY对象 BCECPrivateKey bcecPrivateKey = (BCECPrivateKey) keyFactory.generatePrivate(new ECPrivateKeySpec(bigInteger, ecParameterSpec)); // 获取SM2加密器 Cipher cipher = Cipher.getInstance("SM2", provider); // 初始化为加密模式 cipher.init(Cipher.DECRYPT_MODE, bcecPrivateKey); // 解密 content = new String(cipher.doFinal(Base64.getDecoder().decode(contentDecrypt))); } catch (Exception e) { log.info("SM2Utils.encrypt(java.lang.String, java.lang.String) error {}", e.getMessage(), e); } return content; } public static String decrypt(String privateKey, byte[] contentDecrypt) { return decrypt(privateKey, new String(contentDecrypt)); } public static void main(String[] args) { String publicKey = "043048E9968B72DDF70983B8E305217D94C1E02A5BD4875B625ACC3B13512641A7AD7DF0A1A39F453675EB4B085D8B9E05433E91DBE716E80A7219C2485F28B01F"; System.out.println(encrypt(publicKey, "8F6190402EC4F423")); }}
如有问题,请私信。
xObP8s/gudi/zrPMoaJKU7K5u7e+s7/Os8yhokpBVkHP4LnYv86zzMjn0OjSqtKyv8nS1MGqz7VRUaGjDQoNCtf31d8gUVEgNDA0NTQwMjI5
来源地址:https://blog.csdn.net/liberty888/article/details/131835920