package com.nanjing.water.common.util; import org.springframework.util.Base64Utils; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.nio.charset.StandardCharsets; import java.util.Random; public class SM4Util { /** * 算法名字 */ private static final String NAME = "SM4"; /** * 加密模式以及短快填充方式 */ private static final String ALGORITHM = "SM4/CBC/PKCS5Padding"; /** * 加密使用的初始向量 */ private static final String IV = "0000000000000000"; /** * 密钥长度(128-32位16进制;256-64位16进制) */ private static final int KEY_SIZE = 16; private static final String ALL_STR = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; public static String generateKey() { Random random = new Random(); StringBuffer sb = new StringBuffer(); for (int i = 0; i < KEY_SIZE; i++) { int number = random.nextInt(ALL_STR.length()); sb.append(ALL_STR.charAt(number)); } return sb.toString(); } /** * 使用指定的加密算法和密钥对给定的字节数组进行加密 * * @param content 待加密的原始字符串 * @param key 密钥(注意必须是128bits,即16个字节) * @return 加密后的字符串 * @throws Exception 如果加密时发生错误,则抛出异常 */ public static String encode(String content, String key) throws Exception { try { byte[] inputByte = content.getBytes(StandardCharsets.UTF_8); byte[] keyBuffer = key.getBytes(StandardCharsets.UTF_8); // 获取加密实例 Cipher c = Cipher.getInstance(ALGORITHM); // 根据密钥的字节数组创建 SecretKeySpec SecretKeySpec secretKeySpec = new SecretKeySpec(keyBuffer, NAME); // 创建 IvParameterSpec 对象,使用默认向量和字符集 IvParameterSpec ivParameterSpec = new IvParameterSpec(IV.getBytes(StandardCharsets.UTF_8)); // 初始化加密实例 c.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec); // 返回加密后的字节数组 byte[] buffer = c.doFinal(inputByte); return Base64Utils.encodeToString(buffer); } catch (Exception e) { throw new Exception("加密失败: " + e, e); } } /** * 解密 * * @param content 待解密字符串 * @param key 密钥(注意必须是128bits,即16个字节) * @return 解密后的原始字符串 * @throws Exception 如果解密时发生错误,则抛出异常 */ public static String decode(String content, String key) throws Exception { try { byte[] inputBytes = Base64Utils.decode(content.getBytes(StandardCharsets.UTF_8)); byte[] keyBuffer = key.getBytes(StandardCharsets.UTF_8); Cipher cipher = Cipher.getInstance(ALGORITHM); SecretKeySpec secretKeySpec = new SecretKeySpec(keyBuffer, NAME); IvParameterSpec ivParameterSpec = new IvParameterSpec(IV.getBytes(StandardCharsets.UTF_8)); cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec); byte[] buffer = cipher.doFinal(inputBytes); return new String(buffer, StandardCharsets.UTF_8); } catch (Exception e) { throw new Exception("解密失败: " + e, e); } } }