一:前端vue
二:后端解密
三:后端详解
3.1maven文件
<dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15to18</artifactId><version>1.66</version> </dependency>
3.2工具类(生成公钥、私钥、加密、解密)
public class Sm2Utils {private static final X9ECParameters X9_EC_PARAMETERS = GMNamedCurves.getByName("sm2p256v1");private static final ECParameterSpec EC_DOMAIN_PARAMETERS = new ECParameterSpec(X9_EC_PARAMETERS.getCurve(), X9_EC_PARAMETERS.getG(), X9_EC_PARAMETERS.getN());static {if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {Security.addProvider(new BouncyCastleProvider());}}/*** 生成公私钥对** @return* @throws Exception*/public static KeyPair genePublicPrivate() throws Exception {KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC", "BC");// 初始化密妈生感器keyPairGenerator.initialize(new ECGenParameterSpec("sm2p256v1"), new SecureRandom());//SM2算法所使用的曲线//生成密钥对KeyPair keyPair = keyPairGenerator.generateKeyPair();//获公钥PublicKey publicKey = keyPair.getPublic();// 获私钥PrivateKey privateKey = keyPair.getPrivate();System.out.println("publicKey" + publicKey);System.out.println("privateKey" + privateKey);return keyPair;}/*** 生成公私钥十六进制String* @return* @throws Exception*/public static Map<String, Object> genePublicPrivateMap() throws Exception {Map<String, Object> back = new HashMap<>();KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC", "BC");// 初始化密妈生感器keyPairGenerator.initialize(new ECGenParameterSpec("sm2p256v1"), new SecureRandom());//是、SM2算法所使用的曲线//生密钥对KeyPair keyPair = keyPairGenerator.generateKeyPair();//获公钥PublicKey publicKey = keyPair.getPublic();BCECPublicKey p = (BCECPublicKey) publicKey;String hexPubString = Hex.toHexString(p.getQ().getEncoded(false));System.out.println("publicKeyHex:" + hexPubString);back.put("publicKey", hexPubString);// 获私钥PrivateKey privateKey = keyPair.getPrivate();ECPrivateKey ecprivateKey = (ECPrivateKey) privateKey;String hexPriString = ecprivateKey.getD().toString(16);System.out.println("privateKeyHex:" + hexPriString);back.put("privateKey", hexPriString);return back;}/***字符串转公钥** @param* @return BCECPublicKey*/public static BCECPublicKey convertHexToPublicKey(String publicKeyHex) throws InvalidKeySpecException {if (publicKeyHex.length() > 128) {publicKeyHex = publicKeyHex.substring(publicKeyHex.length() - 128);}String xCoord = publicKeyHex.substring(0, 64);String yCoord = publicKeyHex.substring(64);BigInteger x = new BigInteger(xCoord, 16);BigInteger y = new BigInteger(yCoord, 16);ECPublicKeySpec publicKeySpec = new ECPublicKeySpec(X9_EC_PARAMETERS.getCurve().createPoint(x, y), EC_DOMAIN_PARAMETERS);return new BCECPublicKey("EC", publicKeySpec, BouncyCastleProvider.CONFIGURATION);}/*** 字符串转私钥.* @return BCECPrivateKey*/public static BCECPrivateKey convertHexToPrivateKey(String privateKeyHex) throws InvalidKeySpecException {BigInteger d = new BigInteger(privateKeyHex, 16);ECPrivateKeySpec privateKeySpec = new ECPrivateKeySpec(d, EC_DOMAIN_PARAMETERS);return new BCECPrivateKey("EC", privateKeySpec, BouncyCastleProvider.CONFIGURATION);}/*** 私钥解密* @param cipherData* @param privateKey* @return*/public static String decrypt(String cipherData, String privateKey) {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 back = "";try {byte[] arrayOfBytes = sm2Engine.processBlock(cipherDataByte, 0, cipherDataByte.length);return new String(arrayOfBytes);} catch (Exception e) {System.out.println("SM2解密异常:" + e.getMessage());}return back;}/*** 公钥加密* @param publicKey* @param data* @return*/public static String encrypt(String publicKey, String data) {// 获取一条SM2曲线参数X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");// 构造ECC算法参数,曲线方程、椭圆曲线G点、大整数NECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(), sm2ECParameters.getG(), sm2ECParameters.getN());//提取公钥点ECPoint pukPoint = sm2ECParameters.getCurve().decodePoint(Hex.decode(publicKey));// 公钥前面的02或者03表示是压缩公钥,04表示未压缩公钥, 04的时候,可以去掉前面的04ECPublicKeyParameters 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);}/*** 私钥签名*/public static byte[] signByPrivateKey(byte[] data, PrivateKey privateKey) throws Exception {Signature sig = Signature.getInstance(GMObjectIdentifiers.sm2sign_with_sm3.toString(), BouncyCastleProvider.PROVIDER_NAME);sig.initSign(privateKey);sig.update(data);return sig.sign();}/*** 公钥验签*/public static boolean verifyByPublicKey(byte[] data, PublicKey publicKey, byte[] signature) throws Exception {Signature sig = Signature.getInstance(GMObjectIdentifiers.sm2sign_with_sm3.toString(), BouncyCastleProvider.PROVIDER_NAME);sig.initVerify(publicKey);sig.update(data);return sig.verify(signature);} }