Java实现Sm4加密和解密
程序员文章站
2024-03-14 14:12:46
...
/**
* 国密SM4分组密码算法工具类(对称加密)
* <p>GB/T 32907-2016 信息安全技术 SM4分组密码算法</p>
* <p>SM4-ECB-PKCS5Padding</p>
*/
public class Sm4Util {
private static final String ALGORITHM_NAME = "SM4";
private static final String ALGORITHM_ECB_PKCS5PADDING = "SM4/ECB/PKCS5Padding";
private static final String SM4_KEY = "55934cbe51bdafedd33dc53740607347";
/**
* SM4算法目前只支持128位(即**16字节)
*/
private static final int DEFAULT_KEY_SIZE = 128;
static {
// 防止内存中出现多次BouncyCastleProvider的实例
if (null == Security.getProvider(BouncyCastleProvider.PROVIDER_NAME)) {
Security.addProvider(new BouncyCastleProvider());
}
}
private Sm4Util() {
}
/**
* 生成**
* <p>建议使用DigestUtil.binToHex将二进制转成HEX</p>
*
* @return **16位
* @throws Exception 生成**异常
*/
public static byte[] generateKey() throws Exception {
KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM_NAME, BouncyCastleProvider.PROVIDER_NAME);
kg.init(DEFAULT_KEY_SIZE, new SecureRandom());
return kg.generateKey().getEncoded();
}
/**
* 加密,SM4-ECB-PKCS5Padding
*
* @param data 要加密的明文
* @return 加密后的密文
* @throws Exception 加密异常
*/
public static byte[] encrypt(byte[] data) throws Exception {
return sm4(data, StrUtil.hexToBin(SM4_KEY), Cipher.ENCRYPT_MODE);
}
/**
* 解密,SM4-ECB-PKCS5Padding
*
* @param data 要解密的密文
* @return 解密后的明文
* @throws Exception 解密异常
*/
public static byte[] decrypt(byte[] data) throws Exception {
return sm4(data, StrUtil.hexToBin(SM4_KEY), Cipher.DECRYPT_MODE);
}
/**
* SM4对称加解密
*
* @param input 明文(加密模式)或密文(解密模式)
* @param key **
* @param mode Cipher.ENCRYPT_MODE - 加密;Cipher.DECRYPT_MODE - 解密
* @return 密文(加密模式)或明文(解密模式)
* @throws Exception 加解密异常
*/
private static byte[] sm4(byte[] input, byte[] key, int mode)
throws Exception {
SecretKeySpec sm4Key = new SecretKeySpec(key, ALGORITHM_NAME);
Cipher cipher = Cipher
.getInstance(ALGORITHM_ECB_PKCS5PADDING, BouncyCastleProvider.PROVIDER_NAME);
cipher.init(mode, sm4Key);
return cipher.doFinal(input);
}
}
/**
* 字符串工具类
*
*/
public class StrUtil {
/**
* 字节数组转十六进制字符串
*
* @param bytes 字节数组
* @return 十六进制字符串
*/
public static String binToHex(byte[] bytes) {
return Hex.toHexString(bytes).toUpperCase();
}
/**
* 十六进制字符串转字节数组
*
* @param hex 字节数组
* @return 十六进制字符串
*/
public static byte[] hexToBin(String hex) {
return Hex.decode(hex);
}
/**
* 字节数组转UTF8字符串
*
* @param bytes 字节数组
* @return UTF8字符串
*/
public static String binToStr(byte[] bytes) {
return new String(bytes, StandardCharsets.UTF_8);
}
/**
* UTF8字符串转字节数组
*
* @param str UTF8字符串
* @return 字节数组
*/
public static byte[] strToBin(String str) {
return Strings.toUTF8ByteArray(str);
}
}
上一篇: gRPC之概念