当前位置: 代码迷 >> 综合 >> 关于 SM4 加秘密解密的工具类 (转载)
  详细解决方案

关于 SM4 加秘密解密的工具类 (转载)

热度:98   发布时间:2024-02-22 11:23:19.0

1、需要依赖:

 <dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15on</artifactId><version>1.66</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.4.1</version></dependency>

2、工具类

package com.wlhy.utils;import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.security.Security;
import java.util.Arrays;public class Sm4Util {static {Security.addProvider(new BouncyCastleProvider());}private static final String ENCODING = "UTF-8";public static final String ALGORITHM_NAME = "SM4";// PKCS5Padding  NoPadding 补位规则,PKCS5Padding缺位补0,NoPadding不补public static final String ALGORITHM_NAME_ECB_PADDING = "SM4/ECB/PKCS5Padding";/*** ECB加密模式,无向量* @explain ECB* @param algorithmName* @param mode* @param key* @return* @throws Exception*/private static Cipher generateEcbCipher(String algorithmName, int mode, byte[] key) throws Exception {Cipher cipher = Cipher.getInstance(algorithmName, BouncyCastleProvider.PROVIDER_NAME);Key sm4Key = new SecretKeySpec(key, ALGORITHM_NAME);cipher.init(mode, sm4Key);return cipher;}/*** sm4加密* @explain 加密模式:ECB 密文长度不固定,会随着被加密字符串长度的变化而变化* @param hexKey 16进制密钥(忽略大小写)* @param paramStr 待加密字符串* @return 返回16进制的加密字符串* @throws Exception*/public static String encryptEcb(String hexKey, String paramStr) throws Exception {String cipherText = "";// 16进制字符串-->byte[]byte[] keyData = ByteUtils.fromHexString(hexKey);// String-->byte[]//当加密数据为16进制字符串时使用这行
//	        byte[] srcData = ByteUtils.fromHexString(hexKey);byte[] srcData = paramStr.getBytes(ENCODING);// 加密后的数组byte[] cipherArray = encrypt_Ecb_Padding(keyData, srcData);// byte[]-->hexStringcipherText = ByteUtils.toHexString(cipherArray);return cipherText;}/*** 加密模式之Ecb* @param key* @param data* @return* @throws Exception*/public static byte[] encrypt_Ecb_Padding(byte[] key, byte[] data) throws Exception {Cipher cipher = generateEcbCipher(ALGORITHM_NAME_ECB_PADDING, Cipher.ENCRYPT_MODE, key);//声称Ecb暗号,通过第二个参数判断加密还是解密return cipher.doFinal(data);}//解密****************************************/*** sm4解密* @explain 解密模式:采用ECB* @param hexKey 16进制密钥* @param cipherText 16进制的加密字符串(忽略大小写)* @return 解密后的字符串* @throws Exception*/public static String decryptEcb(String hexKey, String cipherText) throws Exception {// 用于接收解密后的字符串String decryptStr = "";// hexString-->byte[]byte[] keyData = ByteUtils.fromHexString(hexKey);// hexString-->byte[]byte[] cipherData = ByteUtils.fromHexString(cipherText);// 解密byte[] srcData = decrypt_Ecb_Padding(keyData, cipherData);// byte[]-->StringdecryptStr = new String(srcData, ENCODING);return decryptStr;}/*** 解密* @explain* @param key* @param cipherText* @return* @throws Exception*/public static byte[] decrypt_Ecb_Padding(byte[] key, byte[] cipherText) throws Exception {Cipher cipher = generateEcbCipher(ALGORITHM_NAME_ECB_PADDING, Cipher.DECRYPT_MODE, key);//生成Ecb暗号,通过第二个参数判断加密还是解密return cipher.doFinal(cipherText);}public static boolean verifyEcb(String hexKey, String cipherText, String paramStr) throws Exception {// 用于接收校验结果boolean flag = false;// hexString-->byte[]byte[] keyData = ByteUtils.fromHexString(hexKey);// 将16进制字符串转换成数组byte[] cipherData = ByteUtils.fromHexString(cipherText);// 解密byte[] decryptData = decrypt_Ecb_Padding(keyData, cipherData);// 将原字符串转换成byte[]byte[] srcData = paramStr.getBytes(ENCODING);// 判断2个数组是否一致flag = Arrays.equals(decryptData, srcData);return flag;}public static void main(String[] args) {try {System.out.println("开始****************************");String json = "xxxxxx";System.out.println("加密前:"+json);//自定义的32位16进制秘钥String key = "76747161590C11EA8FBA40167E2083BB ";String cipher = encryptEcb(key,json);//sm4加密System.out.println("加密后:"+cipher);System.out.println("校验:"+verifyEcb(key,cipher,json));//校验加密前后是否为同一数据cipher = "jiami";json =decryptEcb(key,cipher);//解密System.out.println("解密后:"+json);System.out.println("结束****************************");} catch (Exception e) {e.printStackTrace();}}}

 

  相关解决方案