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);
|
}
|
}
|
}
|