描述
sm4算法类似AES算法
代码
package org.example.test;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.Security;
import java.util.Base64;
public class SM4Test {
static {
Security.addProvider(new BouncyCastleProvider()); // 注册BouncyCastle
}
public static SecretKey generateSM4Key() throws Exception {
KeyGenerator keyGenerator = KeyGenerator.getInstance("SM4", "BC"); // 指定算法和提供商
keyGenerator.init(128); // SM4密钥长度固定128位
return keyGenerator.generateKey();
}
public static String secretKeyStr() throws NoSuchAlgorithmException, NoSuchProviderException {
KeyGenerator keyGenerator = KeyGenerator.getInstance("SM4", "BC"); // 指定算法和提供商
keyGenerator.init(128); // SM4密钥长度固定128位
byte[] encoded = keyGenerator.generateKey().getEncoded();
return Base64.getEncoder().encodeToString(encoded);
}
public static byte[] sm4Encrypt(byte[] plaintext, SecretKey key) throws Exception {
// 生成随机IV(16字节)
byte[] iv = new byte[16];
SecureRandom random = new SecureRandom();
random.nextBytes(iv);
IvParameterSpec ivSpec = new IvParameterSpec(iv);
// 初始化加密器
Cipher cipher = Cipher.getInstance("SM4/CBC/PKCS7Padding", "BC");
cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);
// 加密数据(最终密文 = IV + 加密内容)
byte[] ciphertext = cipher.doFinal(plaintext);
return concatenateArrays(iv, ciphertext); // 将IV与密文拼接
}
// 工具方法:拼接两个字节数组
private static byte[] concatenateArrays(byte[] a, byte[] b) {
byte[] result = new byte[a.length + b.length];
System.arraycopy(a, 0, result, 0, a.length);
System.arraycopy(b, 0, result, a.length, b.length);
return result;
}
public static byte[] sm4Decrypt(byte[] ciphertextWithIv, SecretKey key) throws Exception {
// 分离IV和密文(前16字节是IV)
byte[] iv = new byte[16];
byte[] ciphertext = new byte[ciphertextWithIv.length - 16];
System.arraycopy(ciphertextWithIv, 0, iv, 0, 16);
System.arraycopy(ciphertextWithIv, 16, ciphertext, 0, ciphertext.length);
IvParameterSpec ivSpec = new IvParameterSpec(iv);
// 初始化解密器
Cipher cipher = Cipher.getInstance("SM4/CBC/PKCS7Padding", "BC");
cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);
// 解密数据
return cipher.doFinal(ciphertext);
}
public static void main(String[] args) throws Exception {
// 生成密钥
// SecretKey key = generateSM4Key();
String keyStr = secretKeyStr();
SecretKeySpec key = new SecretKeySpec(Base64.getDecoder().decode(keyStr),"SM4");
// 加密测试数据
String originalText = "Hello, SM4!";
byte[] encrypted = sm4Encrypt(originalText.getBytes("UTF-8"), key);
// 解密验证
byte[] decrypted = sm4Decrypt(encrypted, key);
String result = new String(decrypted, "UTF-8");
System.out.println("原文: " + originalText);
System.out.println("解密结果: " + result); // 应输出 "Hello, SM4!"
}
}