Java实现SM4加密解密算法详解
一、SM4 算法简介
SM4 是中国国家密码管理局于 2012 年发布的一种对称加密算法,属于分组密码算法。它的分组长度为 128 位(16 字节),密钥长度同样为 128 位(16 字节)。SM4 算法具有较高的安全性和性能,在国内多个领域得到广泛应用。
二、依赖库
要在 Java 中使用 SM4 算法,可借助 Bouncy Castle 库。在 Maven 项目里,需在 pom.xml 文件添加如下依赖:
xml
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.70</version>
</dependency>
三、示例代码
java
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.Security;
import java.util.Base64;
public class SM4Example {
private static final String ALGORITHM_NAME = "SM4";
private static final String ALGORITHM_MODE = "SM4/ECB/PKCS5Padding";
static {
Security.addProvider(new BouncyCastleProvider());
}
/**
* 生成 SM4 密钥
* @return 密钥的 Base64 编码字符串
* @throws Exception 异常
*/
public static String generateKey() throws Exception {
KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM_NAME, "BC");
kg.init(128);
SecretKey secretKey = kg.generateKey();
return Base64.getEncoder().encodeToString(secretKey.getEncoded());
}
/**
* SM4 加密
* @param plainText 明文
* @param key 密钥的 Base64 编码字符串
* @return 密文的 Base64 编码字符串
* @throws Exception 异常
*/
public static String encrypt(String plainText, String key) throws Exception {
byte[] keyBytes = Base64.getDecoder().decode(key);
SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, ALGORITHM_NAME);
Cipher cipher = Cipher.getInstance(ALGORITHM_MODE, "BC");
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
byte[] encryptedBytes = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(encryptedBytes);
}
/**
* SM4 解密
* @param cipherText 密文的 Base64 编码字符串
* @param key 密钥的 Base64 编码字符串
* @return 明文
* @throws Exception 异常
*/
public static String decrypt(String cipherText, String key) throws Exception {
byte[] keyBytes = Base64.getDecoder().decode(key);
SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, ALGORITHM_NAME);
Cipher cipher = Cipher.getInstance(ALGORITHM_MODE, "BC");
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
byte[] cipherBytes = Base64.getDecoder().decode(cipherText);
byte[] decryptedBytes = cipher.doFinal(cipherBytes);
return new String(decryptedBytes, StandardCharsets.UTF_8);
}
public static void main(String[] args) {
try {
// 生成密钥
String key = generateKey();
System.out.println("生成的密钥: " + key);
// 明文
String plainText = "Hello, SM4!";
System.out.println("明文: " + plainText);
// 加密
String cipherText = encrypt(plainText, key);
System.out.println("密文: " + cipherText);
// 解密
String decryptedText = decrypt(cipherText, key);
System.out.println("解密后的明文: " + decryptedText);
} catch (Exception e) {
e.printStackTrace();
}
}
}
四、代码解释
依赖引入:借助 Bouncy Castle 库实现 SM4 算法,在代码开头添加该库的提供者。
常量定义:定义了算法名称 ALGORITHM_NAME 和算法模式 ALGORITHM_MODE。
生成密钥:generateKey 方法用于生成 128 位的 SM4 密钥,并将其转换为 Base64 编码的字符串。
加密方法:encrypt 方法接收明文和密钥,先对密钥进行 Base64 解码,再用 Cipher 类进行加密操作,最后把加密结果转换为 Base64 编码的字符串。
解密方法:decrypt 方法接收密文和密钥,对密文和密钥进行 Base64 解码,使用 Cipher 类进行解密操作,最终返回解密后的明文。
主方法:在 main 方法中,生成密钥,对明文进行加密,然后对密文进行解密,最后输出相关信息。
五、运行示例
运行上述代码,输出结果类似如下:
plaintext
生成的密钥: 8Q+J8p5J+6x6J8l7J8p5J8=
明文: Hello, SM4!
密文: 4a7j8J8l7J8p5J8=
解密后的明文: Hello, SM4!
通过上述步骤,你可以在 Java 中实现 SM4 加密解密功能。
作者:忧郁的狐狸