新增sm2 sm3 sm4加解密

This commit is contained in:
zhuyijun 2022-11-18 23:12:44 +08:00
parent e01a21f652
commit 63ea03eb06
6 changed files with 54 additions and 308 deletions

View File

@ -1,133 +0,0 @@
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package cn.zyjblogs.starter.common.utils.crypto;
import org.bouncycastle.asn1.gm.GMNamedCurves;
import org.bouncycastle.asn1.gm.GMObjectIdentifiers;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.engines.SM2Engine;
import org.bouncycastle.crypto.engines.SM2Engine.Mode;
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 org.bouncycastle.jce.spec.ECPrivateKeySpec;
import org.bouncycastle.jce.spec.ECPublicKeySpec;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.util.encoders.Hex;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.ECGenParameterSpec;
import java.util.Base64;
public class Sm2Utils {
private static X9ECParameters x9ECParameters = GMNamedCurves.getByName("sm2p256v1");
private static byte SM2_CIPHER_FIRST_BIT = 4;
private static ECParameterSpec param;
private Sm2Utils() {
}
public static String encrypt(String publicKey, String data) throws Exception {
return encrypt(publicKey, data, Mode.C1C3C2);
}
public static String encrypt(String publicKey, String data, SM2Engine.Mode mode) throws Exception {
BCECPublicKey bcecPublicKey = getPublicKey(publicKey);
ECParameterSpec parameters = bcecPublicKey.getParameters();
ECDomainParameters ecDomainParameters = new ECDomainParameters(parameters.getCurve(), parameters.getG(), parameters.getN());
ECPublicKeyParameters ecPublicKeyParameters = new ECPublicKeyParameters(bcecPublicKey.getQ(), ecDomainParameters);
SM2Engine sm2Engine = new SM2Engine(mode);
sm2Engine.init(true, new ParametersWithRandom(ecPublicKeyParameters, new SecureRandom()));
byte[] in = data.getBytes(StandardCharsets.UTF_8);
byte[] bytes = sm2Engine.processBlock(in, 0, in.length);
byte[] base64Bytes = Base64.getEncoder().encode(bytes);
return new String(base64Bytes, StandardCharsets.UTF_8);
}
public static String decrypt(String privateKey, String data) throws Exception {
return decrypt(privateKey, data, Mode.C1C3C2);
}
public static String decrypt(String privateKey, String data, SM2Engine.Mode mode) throws Exception {
byte[] base64Decode = Base64.getDecoder().decode(data.getBytes(StandardCharsets.UTF_8));
byte[] finalByte = addBitIfNeed(base64Decode);
BCECPrivateKey bcecPrivateKey = getPrivateKey(privateKey);
ECParameterSpec parameters = bcecPrivateKey.getParameters();
ECDomainParameters ecDomainParameters = new ECDomainParameters(parameters.getCurve(), parameters.getG(), parameters.getN());
ECPrivateKeyParameters ecPublicKeyParameters = new ECPrivateKeyParameters(bcecPrivateKey.getD(), ecDomainParameters);
SM2Engine sm2Engine = new SM2Engine(mode);
sm2Engine.init(false, ecPublicKeyParameters);
byte[] bytes = sm2Engine.processBlock(finalByte, 0, finalByte.length);
return new String(bytes, StandardCharsets.UTF_8);
}
public static String sign(String privateKey, String data) throws Exception {
Signature signature = Signature.getInstance(GMObjectIdentifiers.sm2sign_with_sm3.toString());
BCECPrivateKey bcecPrivateKey = getPrivateKey(privateKey);
signature.initSign(bcecPrivateKey);
signature.update(data.getBytes(StandardCharsets.UTF_8));
byte[] sign = signature.sign();
return Base64.getEncoder().encodeToString(sign);
}
public static boolean verify(String publicKey, String data, String sign) throws Exception {
byte[] decode = Base64.getDecoder().decode(sign.getBytes(StandardCharsets.UTF_8));
Signature signature = Signature.getInstance(GMObjectIdentifiers.sm2sign_with_sm3.toString());
BCECPublicKey bcecPublicKey = getPublicKey(publicKey);
signature.initVerify(bcecPublicKey);
signature.update(data.getBytes(StandardCharsets.UTF_8));
return signature.verify(decode);
}
public static void generateKey() throws Exception {
ECGenParameterSpec sm2Spec = new ECGenParameterSpec("sm2p256v1");
KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", new BouncyCastleProvider());
kpg.initialize(sm2Spec, new SecureRandom());
KeyPair keyPair = kpg.generateKeyPair();
BCECPublicKey bcecPublicKey = (BCECPublicKey) keyPair.getPublic();
String publicKey = Hex.toHexString(bcecPublicKey.getQ().getEncoded(false));
System.out.println("公钥:\n" + publicKey);
BCECPrivateKey bcecPrivateKey = (BCECPrivateKey) keyPair.getPrivate();
String privateKey = bcecPrivateKey.getD().toString(16);
System.out.println("私钥:\n" + privateKey);
}
private static BCECPublicKey getPublicKey(String publicKey) throws Exception {
KeyFactory keyFactory = KeyFactory.getInstance("EC");
ECPoint ecPoint = param.getCurve().decodePoint(Hex.decode(publicKey));
return (BCECPublicKey) keyFactory.generatePublic(new ECPublicKeySpec(ecPoint, param));
}
private static BCECPrivateKey getPrivateKey(String privateKey) throws Exception {
BigInteger d = new BigInteger(privateKey, 16);
KeyFactory keyFactory = KeyFactory.getInstance("EC");
return (BCECPrivateKey) keyFactory.generatePrivate(new ECPrivateKeySpec(d, param));
}
private static byte[] addBitIfNeed(byte[] base64Decode) {
byte first = base64Decode[0];
if (first == SM2_CIPHER_FIRST_BIT) {
return base64Decode;
} else {
byte[] finalByte = new byte[base64Decode.length + 1];
finalByte[0] = SM2_CIPHER_FIRST_BIT;
System.arraycopy(base64Decode, 0, finalByte, 1, base64Decode.length);
return finalByte;
}
}
static {
param = new ECParameterSpec(x9ECParameters.getCurve(), x9ECParameters.getG(), x9ECParameters.getN(), x9ECParameters.getH());
Security.addProvider(new BouncyCastleProvider());
}
}

View File

@ -1,62 +0,0 @@
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package cn.zyjblogs.starter.common.utils.crypto;
import java.nio.charset.StandardCharsets;
import java.security.Security;
import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Hex;
public class Sm3Utils {
public Sm3Utils() {
}
public static String hash(String data) {
byte[] hash = hash(data.getBytes(StandardCharsets.UTF_8));
return Hex.toHexString(hash);
}
public static byte[] hash(byte[] data) {
SM3Digest digest = new SM3Digest();
digest.update(data, 0, data.length);
byte[] hash = new byte[digest.getDigestSize()];
digest.doFinal(hash, 0);
return hash;
}
public static String hmac(String key, String data) {
byte[] hmac = hmac(key.getBytes(StandardCharsets.UTF_8), data.getBytes(StandardCharsets.UTF_8));
return Hex.toHexString(hmac);
}
public static byte[] hmac(byte[] key, byte[] data) {
KeyParameter keyParameter = new KeyParameter(key);
SM3Digest digest = new SM3Digest();
HMac mac = new HMac(digest);
mac.init(keyParameter);
mac.update(data, 0, data.length);
byte[] result = new byte[mac.getMacSize()];
mac.doFinal(result, 0);
return result;
}
public static boolean verify(String data, String hash) {
String srcHash = hash(data);
return hash.equals(srcHash);
}
public static boolean verify(String key, String data, String hmac) {
String srcHmac = hmac(key, data);
return hmac.equals(srcHmac);
}
static {
Security.addProvider(new BouncyCastleProvider());
}
}

View File

@ -1,104 +0,0 @@
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package cn.zyjblogs.starter.common.utils.crypto;
import java.nio.charset.StandardCharsets;
import java.security.AlgorithmParameters;
import java.security.Key;
import java.security.Security;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
public class Sm4Utils {
public static final String ALGORITHM_NAME = "SM4";
public static final String ALGORITHM_NAME_CBC_PADDING = "SM4/CBC/PKCS5Padding";
public static final String ALGORITHM_NAME_ECB_PADDING = "SM4/ECB/PKCS5Padding";
private Sm4Utils() {
}
public static String encryptCbcBase64(String key, String iv, String cipherText) throws Exception {
return encryptCbcBase64(key.getBytes(StandardCharsets.UTF_8), iv.getBytes(StandardCharsets.UTF_8), cipherText.getBytes(StandardCharsets.UTF_8));
}
public static String decryptCbcBase64(String key, String iv, String cipherText) throws Exception {
return decryptCbcBase64(key.getBytes(StandardCharsets.UTF_8), iv.getBytes(StandardCharsets.UTF_8), cipherText.getBytes(StandardCharsets.UTF_8));
}
public static String encryptCbcBase64(byte[] key, byte[] iv, byte[] cipherText) throws Exception {
byte[] bytes = encryptCbc(key, iv, cipherText);
byte[] base64Encode = Base64.getEncoder().encode(bytes);
return new String(base64Encode, StandardCharsets.UTF_8);
}
public static String decryptCbcBase64(byte[] key, byte[] iv, byte[] cipherText) throws Exception {
byte[] base64Decode = Base64.getDecoder().decode(cipherText);
byte[] bytes = decryptCbc(key, iv, base64Decode);
return new String(bytes, StandardCharsets.UTF_8);
}
public static byte[] encryptCbc(byte[] key, byte[] iv, byte[] cipherText) throws Exception {
Cipher cipher = generateCbcCipher(1, key, iv);
return cipher.doFinal(cipherText);
}
public static byte[] decryptCbc(byte[] key, byte[] iv, byte[] cipherText) throws Exception {
Cipher cipher = generateCbcCipher(2, key, iv);
return cipher.doFinal(cipherText);
}
public static String encryptEcbBase64(String key, String cipherText) throws Exception {
return encryptEcbBase64(key.getBytes(StandardCharsets.UTF_8), cipherText.getBytes(StandardCharsets.UTF_8));
}
public static String decryptEcbBase64(String key, String cipherText) throws Exception {
return decryptEcbBase64(key.getBytes(StandardCharsets.UTF_8), cipherText.getBytes(StandardCharsets.UTF_8));
}
public static String encryptEcbBase64(byte[] key, byte[] cipherText) throws Exception {
byte[] bytes = encryptEcb(key, cipherText);
byte[] base64Encode = Base64.getEncoder().encode(bytes);
return new String(base64Encode, StandardCharsets.UTF_8);
}
public static String decryptEcbBase64(byte[] key, byte[] cipherText) throws Exception {
byte[] base64Decode = Base64.getDecoder().decode(cipherText);
byte[] bytes = decryptEcb(key, base64Decode);
return new String(bytes, StandardCharsets.UTF_8);
}
public static byte[] encryptEcb(byte[] key, byte[] cipherText) throws Exception {
Cipher cipher = generateEcbCipher(1, key);
return cipher.doFinal(cipherText);
}
public static byte[] decryptEcb(byte[] key, byte[] cipherText) throws Exception {
Cipher cipher = generateEcbCipher(2, key);
return cipher.doFinal(cipherText);
}
private static Cipher generateCbcCipher(int mode, byte[] key, byte[] iv) throws Exception {
Cipher cipher = Cipher.getInstance("SM4/CBC/PKCS5Padding", "BC");
Key sm4Key = new SecretKeySpec(key, "SM4");
AlgorithmParameters params = AlgorithmParameters.getInstance("SM4");
params.init(iv);
cipher.init(mode, sm4Key, params);
return cipher;
}
private static Cipher generateEcbCipher(int mode, byte[] key) throws Exception {
Cipher cipher = Cipher.getInstance("SM4/ECB/PKCS5Padding", "BC");
Key sm4Key = new SecretKeySpec(key, "SM4");
cipher.init(mode, sm4Key);
return cipher;
}
static {
Security.addProvider(new BouncyCastleProvider());
}
}

View File

@ -1,6 +1,5 @@
package cn.zyjblogs.starter.common.utils.crypto.sm.sm2;
import cn.zyjblogs.starter.common.utils.crypto.Sm2Utils;
import cn.zyjblogs.starter.common.utils.crypto.sm.GmSmException;
import org.bouncycastle.asn1.gm.GMNamedCurves;
import org.bouncycastle.asn1.gm.GMObjectIdentifiers;
@ -381,6 +380,20 @@ public class SM2 {
System.out.println(decrypt7);
String decrypt8 = SM2.decrypt(pri, data, 1, EncodeType.BASE64, SM2.EncodeType.UTF8);
System.out.println(decrypt8);
String datanew = "BPCv4lM/sVXzEJ7uFkXrvuKUVFS3EU9uCkV9vhgJQb92cY3FWfIa1M1UtYxkbfleEdiZHZooh5DV3HaakkYsCTbR/lKF4FC3ZplGGf9rCbCuovf7fFf5TJwX2m83qkNMTuW4o9QdjOQu4MiFtYbTMMTSb/0kNKHkrT8mCSY+6yLg7XIHmzepoGiWhQ2KB9diF066YzjKNDGbP3u9/zoQBCFKr190G7F6NH042kfLPRrpV3IkewJbNKGCCQ0SIvNJ475beYq5jpRbug2WOsR8qLEsPsIl7SPXh0ezB1hLwgmqFqM/B3QbobKP+lFmtbjjIumLgdGM9OzmG82TFZM3k0piIYQPS6JPHjR3nqrnxpwYxn2bKUifnrrrM8smyoa99BzJ4IPnZ7/3oxLwkRFnMee8oyMy1WCab0k5OKmAM/dk2weflyhXyY5mxGYHjdjpsj9ipOcKjqF6LKobMxSAOpn+pRfywvJr/CKE1dcq7k1gK/xZozQVqyENoM3BEyVEYfEUHrI1pxG8/2ugYYXIN4jX6XqR8COxnJOS8XuPi8Ukqsx/E3EwgWEbI3PvtRRaiI4RNWyc1oMyNDr8Al5caf67cUo2pasoF8IrUlZtePBEAmITHfzVm9sCfGz4eNw5b2a5YSLofCYX7R6C0b/+69uutyhmLb3Na9TOyseTEYJcf0pzO8DHdWZDTldH8+swARdulURCBR3AMs2ePDnfJwMcEyNt1jpacVDSRPIVhxOcgdeD3juaYpiEYdVTPBHv+RJoOi6pv87ZheeDejjpGUMLAGEC/P+SpGdG8IT7THEPw16/hNK/lzqAzmYa7lkAH2WycWbnaBed3bHJbJBNjP9DsBpAf3V/PGreXNWeD66g+gCQDhyOUdiWqoaEoCLA7nkOcQqEeDZNegQn5ZfU/cW4yW1sxfb3CNzqxJaA/qayon+BeCYmy3FpA0SIkAbA0/qTG7VWg4u4kAQBG+FZ+lJ9Eaj9JaFiCgqfQRBMEoLuVdH24UeRljIfRptuYDcPydCFRzDWhYqwguPeGluEb9JO8eESZ+waX48xtniMvxbQ0CzfDlMWJwO9EiPJyIj2b86/ibBfSq9vuWwSdeLLL2Jvjn5LB9cwzSU8yQzLgle9YGSC0sbQIMuyFHUhDUVyFTVPE3/bYpotuetoeQVMYvLe9H73825Q6PxY+CCMHb0Jqjva2JAf6emYGx1vb5MGoJzoxz/7lSxJ56I9yMfrwLMljToMSufcV+bhQYb6r468qtQ10eXlKom/I8ZqZIJHsIaZBxsxJe1UyxqGitasg55gqNLLDwv+6UmnvGT/B6g9bmfc363/gO5mQlJfZSlpUodZrXMCYZmNI1ZZFRQbu5aEdtL9M2lXeCnTJa2GDOqpbG5I3aWVcepUcCsx4375bJOo3g24dwhzTCyh7/dW9sPhqb3SSXb/l+JxFzUoBXzxQgpBzakwq1uGrCKYPkNfYrmxRej87ZGgQFGlCVjEUHwRhvnkLHTXeP2f3b8zCeu+6us=";
String decrypt9 = SM2.decrypt(pri, datanew, 1, EncodeType.BASE64, SM2.EncodeType.UTF8);
System.out.println(decrypt9);
SM2KeyPair sm2KeyPair = generateSm2Keys(true);
System.out.println("公钥\n" + sm2KeyPair.getPublicKey());
System.out.println("私钥\n" + sm2KeyPair.getPrivateKey());
String a = SM2.encrypt(sm2KeyPair.getPublicKey(), "好吃啊");
System.out.println(a);
System.out.println(SM2.decrypt(sm2KeyPair.getPrivateKey(), a));
String data1 = "c4eba3e104f1858a4ad0eeea125537e80ad28d10e6b084c26a1c318dba4bec334bf246cdd3900bc35e20a2c8bf6948a050f5c9077b0617db7d98489c37f3cc8aebebf98a39c0f127e6d37a8ec31f3968f07c7a01b8d3e1a554d53b75de8ede6d50050d8a1c60e976e74829b0f32bc049edf7";
System.out.println(SM2.decrypt("69A124C827FA42573FF1047368BA8428C04A04B5B947BBD202956CF1A78D1FB0", data1, 1, EncodeType.HEX, EncodeType.UTF8));
String sign = SM2.sign("69A124C827FA42573FF1047368BA8428C04A04B5B947BBD202956CF1A78D1FB0", data1);
System.out.println("私钥签名:\n" + sign);
System.out.println(SM2.verify("032AB168CD73ED25824DB20B5F190C7C54971BC821450DEE0AC84C779CF3A9F897", data1, sign));
} catch (Exception e) {
throw new RuntimeException(e);
}

View File

@ -1,6 +1,8 @@
package cn.zyjblogs.starter.common.utils.crypto.sm.sm3;
import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.util.encoders.Hex;
import java.nio.charset.StandardCharsets;
@ -12,25 +14,46 @@ import java.util.Locale;
public class SM3 {
public static String digest(String input) {
// 创建摘要器
SM3Digest sm3Digest = new SM3Digest();
// 解析输入数据
byte[] bytes = input.getBytes(StandardCharsets.UTF_8);
// 构造输出数据缓冲区
byte[] out = new byte[32];
// 设置待摘要字节数据
sm3Digest.update(bytes, 0, bytes.length);
// 执行摘要
sm3Digest.doFinal(out, 0);
// 返回HEX字符串
return Hex.toHexString(out).toUpperCase(Locale.ROOT);
}
public static String hmac(String key, String data) {
byte[] bytes = data.getBytes(StandardCharsets.UTF_8);
KeyParameter keyParameter = new KeyParameter(key.getBytes(StandardCharsets.UTF_8));
SM3Digest digest = new SM3Digest();
HMac mac = new HMac(digest);
mac.init(keyParameter);
mac.update(bytes, 0, bytes.length);
byte[] out = new byte[32];
mac.doFinal(out, 0);
return Hex.toHexString(out).toUpperCase(Locale.ROOT);
}
public static boolean verify(String data, String hash) {
String srcHash = digest(data);
return hash.equals(srcHash);
}
public static boolean verify(String key, String data, String hmac) {
String srcHmac = hmac(key, data);
return hmac.equals(srcHmac);
}
public static void main(String[] args) {
String a = SM3.digest("aaaa");
System.out.println(a);
System.out.println(verify("aaaa", a));
}
}

View File

@ -120,7 +120,6 @@ public class SM4 {
// 初始化
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
// 调用加密方法
byte[] outputBytes = cipher.doFinal(Hex.decode(cipherDataHex));
@ -187,4 +186,14 @@ public class SM4 {
}
public static void main(String[] args) throws Exception {
String s = SM4.generateKey();
String iv = "fedcba98765432100123456789abcdef";
System.out.println(s);
String v = SM4.encrypt(s, "欢快", iv);
System.out.println(v);
System.out.println(SM4.decrypt(s, v, iv));
System.out.println(SM4.decrypt("864669EB9E57E15C923E1003CBEA8872", "6a05d74bda1f2a41c0b47605b06ef638", iv));
}
}