SM4加密算法
/*** SM4加密工具类* SM4算法是一种分组密码算法,分组长度为128位,密钥长度为128位*/
public class SM4Util {static {// 加入BouncyCastle支持Security.addProvider(new BouncyCastleProvider());}// 算法名称public static final String ALGORITHM_NAME = "SM4";// 加密算法/分组加密模式/填充方式public static final String ALGORITHM_NAME_ECB_PADDING = "SM4/ECB/PKCS5Padding";public static final String ALGORITHM_NAME_CBC_PADDING = "SM4/CBC/PKCS5Padding";// 密钥长度,128位public static final int KEY_SIZE = 128;/*** 生成ECB模式的密钥* @return 16位密钥* @throws Exception 异常*/public static String generateKey() throws Exception {KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM_NAME, BouncyCastleProvider.PROVIDER_NAME);kg.init(KEY_SIZE, new SecureRandom());return ByteUtils.toHexString(kg.generateKey().getEncoded());}/*** 生成CBC模式的初始化向量* @return 16位初始化向量*/public static String generateIV() {SecureRandom random = new SecureRandom();byte[] iv = new byte[16];random.nextBytes(iv);return ByteUtils.toHexString(iv);}/*** ECB模式加密* @param plainText 明文* @param key 密钥(16位十六进制字符串)* @return 加密后的Base64字符串* @throws Exception 异常*/public static String encryptEcb(String plainText, String key) throws Exception {// 将密钥转换为字节数组byte[] keyData = ByteUtils.fromHexString(key);// 初始化密钥Key secretKey = new SecretKeySpec(keyData, ALGORITHM_NAME);// 实例化加密器Cipher cipher = Cipher.getInstance(ALGORITHM_NAME_ECB_PADDING, BouncyCastleProvider.PROVIDER_NAME);cipher.init(Cipher.ENCRYPT_MODE, secretKey);// 加密byte[] encryptedData = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));// 返回Base64编码结果return Base64.getEncoder().encodeToString(encryptedData);}/*** ECB模式解密* @param cipherText 加密后的Base64字符串* @param key 密钥(16位十六进制字符串)* @return 解密后的明文* @throws Exception 异常*/public static String decryptEcb(String cipherText, String key) throws Exception {// 解码Base64byte[] encryptedData = Base64.getDecoder().decode(cipherText);// 将密钥转换为字节数组byte[] keyData = ByteUtils.fromHexString(key);// 初始化密钥Key secretKey = new SecretKeySpec(keyData, ALGORITHM_NAME);// 实例化解密器Cipher cipher = Cipher.getInstance(ALGORITHM_NAME_ECB_PADDING, BouncyCastleProvider.PROVIDER_NAME);cipher.init(Cipher.DECRYPT_MODE, secretKey);// 解密byte[] decryptedData = cipher.doFinal(encryptedData);return new String(decryptedData, StandardCharsets.UTF_8);}/*** CBC模式加密* @param plainText 明文* @param key 密钥(16位十六进制字符串)* @param iv 初始化向量(16位十六进制字符串)* @return 加密后的Base64字符串* @throws Exception 异常*/public static String encryptCbc(String plainText, String key, String iv) throws Exception {// 将密钥和IV转换为字节数组byte[] keyData = ByteUtils.fromHexString(key);byte[] ivData = ByteUtils.fromHexString(iv);// 初始化密钥和IVKey secretKey = new SecretKeySpec(keyData, ALGORITHM_NAME);IvParameterSpec ivParameterSpec = new IvParameterSpec(ivData);// 实例化加密器Cipher cipher = Cipher.getInstance(ALGORITHM_NAME_CBC_PADDING, BouncyCastleProvider.PROVIDER_NAME);cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec);// 加密byte[] encryptedData = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));return Base64.getEncoder().encodeToString(encryptedData);}/*** CBC模式解密* @param cipherText 加密后的Base64字符串* @param key 密钥(16位十六进制字符串)* @param iv 初始化向量(16位十六进制字符串)* @return 解密后的明文* @throws Exception 异常*/public static String decryptCbc(String cipherText, String key, String iv) throws Exception {// 解码Base64byte[] encryptedData = Base64.getDecoder().decode(cipherText);// 将密钥和IV转换为字节数组byte[] keyData = ByteUtils.fromHexString(key);byte[] ivData = ByteUtils.fromHexString(iv);// 初始化密钥和IVKey secretKey = new SecretKeySpec(keyData, ALGORITHM_NAME);IvParameterSpec ivParameterSpec = new IvParameterSpec(ivData);// 实例化解密器Cipher cipher = Cipher.getInstance(ALGORITHM_NAME_CBC_PADDING, BouncyCastleProvider.PROVIDER_NAME);cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);// 解密byte[] decryptedData = cipher.doFinal(encryptedData);return new String(decryptedData, StandardCharsets.UTF_8);}
}