SM4国密算法加解密工具类(JAVA版) Java版国密SM4算法加解密工具类

1.引入maven依赖


 org.bouncycastle
 bcprov-jdk18on
 1.78

2.新增SM4Util代码

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Hex;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.security.SecureRandom;
import java.security.Security;
import java.util.Arrays;
/**
 * @Author cy
 * @Description sm4加密算法工具类
 * @Date 2024/4/16
 */
public class SM4Util {
 static {
 Security.addProvider(new BouncyCastleProvider());
 }
 private static final String ENCODING = "UTF-8";
 public static final String ALGORITHM_NAME = "SM4";
 // 加密算法/分组加密模式/分组填充方式
 // PKCS5Padding-以8个字节为一组进行分组加密
 // 定义分组加密模式使用:PKCS5Padding
 public static final String ALGORITHM_NAME_ECB_PADDING = "SM4/ECB/PKCS5Padding";
 // 128-32位16进制;256-64位16进制
 public static final int DEFAULT_KEY_SIZE = 128;
 /**
 * 生成ECB暗号
 *
 * @param mode 模式
 * @param key
 * @return
 * @throws Exception
 * @explain ECB模式(电子密码本模式:Electronic codebook)
 */
 private static Cipher generateEcbCipher(int mode, byte[] key) throws Exception {
 Cipher cipher = Cipher.getInstance(SM4Util.ALGORITHM_NAME_ECB_PADDING, BouncyCastleProvider.PROVIDER_NAME);
 Key sm4Key = new SecretKeySpec(key, ALGORITHM_NAME);
 cipher.init(mode, sm4Key);
 return cipher;
 }
 /**
 * 自动生成密钥
 * @return
 * @throws Exception
 */
 public static String generateKey() throws Exception {
 return new String(Hex.encode(generateKey(DEFAULT_KEY_SIZE)));
 }
 /**
 * @param keySize
 * @return
 * @throws Exception
 * @explain
 */
 public static byte[] generateKey(int keySize) throws Exception {
 KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM_NAME, BouncyCastleProvider.PROVIDER_NAME);
 kg.init(keySize, new SecureRandom());
 return kg.generateKey().getEncoded();
 }
 /**
 * sm4加密
 *
 * @param hexKey 16进制密钥(忽略大小写)
 * @param paramStr 待加密字符串
 * @return 返回16进制的加密字符串
 * @throws Exception
 * @explain 加密模式:ECB
 * 密文长度不固定,会随着被加密字符串长度的变化而变化
 */
 public static String encryptEcb(String hexKey, String paramStr) throws Exception {
 String cipherText;
 // 16进制字符串-->byte[]
 byte[] keyData = Hex.decode(hexKey);
 // String-->byte[]
 byte[] srcData = paramStr.getBytes(ENCODING);
 // 加密后的数组
 byte[] cipherArray = encryptEcbPadding(keyData, srcData);
 // byte[]-->hexString
 cipherText = Hex.toHexString(cipherArray);
 return cipherText;
 }
 /**
 * 加密模式之Ecb
 *
 * @param key
 * @param data
 * @return
 * @throws Exception
 * @explain
 */
 public static byte[] encryptEcbPadding(byte[] key, byte[] data) throws Exception {
 Cipher cipher = generateEcbCipher(Cipher.ENCRYPT_MODE, key);
 return cipher.doFinal(data);
 }
 /**
 * sm4解密
 *
 * @param hexKey 16进制密钥
 * @param cipherText 16进制的加密字符串(忽略大小写)
 * @return 解密后的字符串
 * @throws Exception
 * @explain 解密模式:采用ECB
 */
 public static String decryptEcb(String hexKey, String cipherText) throws Exception {
 // 用于接收解密后的字符串
 String decryptStr = "";
 // hexString-->byte[]
 byte[] keyData = Hex.decode(hexKey);
 // hexString-->byte[]
 byte[] cipherData = Hex.decode(cipherText);
 // 解密
 byte[] srcData = decryptEcbPadding(keyData, cipherData);
 // byte[]-->String
 decryptStr = new String(srcData, ENCODING);
 return decryptStr;
 }
 /**
 * 解密
 *
 * @param key
 * @param cipherText
 * @return
 * @throws Exception
 */
 public static byte[] decryptEcbPadding(byte[] key, byte[] cipherText) throws Exception {
 Cipher cipher = generateEcbCipher(Cipher.DECRYPT_MODE, key);
 return cipher.doFinal(cipherText);
 }
 /**
 * 校验加密前后的字符串是否为同一数据
 *
 * @param hexKey 16进制密钥(忽略大小写)
 * @param cipherText 16进制加密后的字符串
 * @param paramStr 加密前的字符串
 * @return 是否为同一数据
 * @throws Exception
 */
 public static boolean verifyEcb(String hexKey, String cipherText, String paramStr) throws Exception {
 // 用于接收校验结果
 boolean flag;
 // hexString-->byte[]
 byte[] keyData = Hex.decode(hexKey);
 // 将16进制字符串转换成数组
 byte[] cipherData = Hex.decode(cipherText);
 // 解密
 byte[] decryptData = decryptEcbPadding(keyData, cipherData);
 // 将原字符串转换成byte[]
 byte[] srcData = paramStr.getBytes(ENCODING);
 // 判断2个数组是否一致
 flag = Arrays.equals(decryptData, srcData);
 return flag;
 }
 public static void main(String[] args) {
 try {
 String data = "测试1234567";
 //生成key
 String key = generateKey();
 System.out.println("key:" + key);
 //加密
 System.out.println("加密前:" + data);
 String cipher = SM4Util.encryptEcb(key, data);
 System.out.println("加密后:"+cipher);
 //判断是否正确
 System.out.println("结果是否正确:" + SM4Util.verifyEcb(key, cipher, data));
 //解密
 String res = SM4Util.decryptEcb(key, cipher);
 System.out.println("解密后:"+res);
 } catch (Exception e) {
 System.out.printf(e.getMessage());
 }
 }
}

3.验证结果

作者:SuperChay原文地址:https://blog.csdn.net/cy364328541/article/details/137841428

%s 个评论

要回复文章请先登录注册