Java实现国密算法SM4/SM3详解及封装工具类(附对称/非对称加密对比)
1. 加密算法基础概念
(1)对称加密 vs 非对称加密
特性 | 对称加密(如SM4/AES) | 非对称加密(如SM2/RSA) |
---|---|---|
密钥 | 加密/解密使用相同密钥 | 公钥加密,私钥解密 |
速度 | 快(适合大数据加密) | 慢(适合小数据加密) |
用途 | 数据加密存储/传输 | 数字签名、密钥交换 |
典型算法 | SM4、AES、DES | SM2、RSA、ECC |
(2)国密算法简介
- SM1:对称加密(硬件实现,不公开)
- SM2:基于ECC的非对称加密(替代RSA)
- SM3:摘要算法(替代SHA-256)
- SM4:对称加密(替代AES)
2. 完整工具类封装
(1)SM4加密工具类
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.*;
import java.util.Base64;
public class Sm4Utils {
static {
Security.addProvider(new BouncyCastleProvider());
}
/**
* 生成SM4密钥(16字节)
*/
public static byte[] generateKey() throws Exception {
KeyGenerator kg = KeyGenerator.getInstance("SM4", "BC");
kg.init(128); // 128位密钥
return kg.generateKey().getEncoded();
}
/**
* SM4加密(CBC模式)
* @param data 明文
* @param key 16字节密钥
* @param iv 16字节初始化向量
*/
public static String encrypt(String data, byte[] key, byte[] iv) throws Exception {
Cipher cipher = Cipher.getInstance("SM4/CBC/PKCS5Padding", "BC");
SecretKeySpec keySpec = new SecretKeySpec(key, "SM4");
IvParameterSpec ivSpec = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
byte[] encrypted = cipher.doFinal(data.getBytes());
return Base64.getEncoder().encodeToString(encrypted);
}
/**
* SM4解密
*/
public static String decrypt(String encryptedData, byte[] key, byte[] iv) throws Exception {
Cipher cipher = Cipher.getInstance("SM4/CBC/PKCS5Padding", "BC");
SecretKeySpec keySpec = new SecretKeySpec(key, "SM4");
IvParameterSpec ivSpec = new IvParameterSpec(iv);
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
byte[] decrypted = cipher.doFinal(Base64.getDecoder().decode(encryptedData));
return new String(decrypted);
}
}
(2)SM3摘要工具类
import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.util.encoders.Hex;
public class Sm3Utils {
/**
* 生成SM3摘要(32字节)
*/
public static String hash(String data) {
SM3Digest digest = new SM3Digest();
byte[] bytes = data.getBytes();
digest.update(bytes, 0, bytes.length);
byte[] hash = new byte[digest.getDigestSize()];
digest.doFinal(hash, 0);
return Hex.toHexString(hash);
}
/**
* 文件摘要计算
*/
public static String hashFile(byte[] fileData) {
SM3Digest digest = new SM3Digest();
digest.update(fileData, 0, fileData.length);
byte[] hash = new byte[digest.getDigestSize()];
digest.doFinal(hash, 0);
return Hex.toHexString(hash);
}
}
(3)SM2非对称加密工具类(需BC支持)
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.security.*;
import java.security.spec.*;
public class Sm2Utils {
static {
Security.addProvider(new BouncyCastleProvider());
}
/**
* 生成SM2密钥对
*/
public static KeyPair generateKeyPair() throws Exception {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", "BC");
kpg.initialize(SM2Params.DOMAIN_PARAMS); // 使用SM2预设参数
return kpg.generateKeyPair();
}
/**
* 公钥加密
*/
public static byte[] encrypt(byte[] data, PublicKey publicKey) throws Exception {
Cipher cipher = Cipher.getInstance("SM2", "BC");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(data);
}
/**
* 私钥解密
*/
public static byte[] decrypt(byte[] encryptedData, PrivateKey privateKey) throws Exception {
Cipher cipher = Cipher.getInstance("SM2", "BC");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(encryptedData);
}
}
3. 完整使用示例
(1)SM4示例
public static void main(String[] args) throws Exception {
// 生成密钥和IV
byte[] key = Sm4Utils.generateKey();
byte[] iv = new byte[16]; // 实际项目应使用SecureRandom生成
// 加密
String encrypted = Sm4Utils.encrypt("Hello SM4", key, iv);
System.out.println("加密结果: " + encrypted);
// 解密
String decrypted = Sm4Utils.decrypt(encrypted, key, iv);
System.out.println("解密结果: " + decrypted);
}
(2)SM3示例
String hash = Sm3Utils.hash("Hello SM3");
System.out.println("SM3摘要: " + hash); // 输出32字节十六进制字符串
(3)SM2示例
KeyPair keyPair = Sm2Utils.generateKeyPair();
byte[] encrypted = Sm2Utils.encrypt("Hello SM2".getBytes(), keyPair.getPublic());
byte[] decrypted = Sm2Utils.decrypt(encrypted, keyPair.getPrivate());
System.out.println("SM2解密: " + new String(decrypted));
4. 性能与安全建议
(1)算法选择指南
场景 | 推荐算法 |
---|---|
大数据加密 | SM4(对称加密) |
密钥传输/数字签名 | SM2(非对称加密) |
密码存储/完整性校验 | SM3(摘要算法) |
(2)最佳实践
- 密钥管理:
- 对称加密密钥需定期更换
- 非对称加密私钥必须安全存储(HSM/KeyStore)
- 模式选择:
- SM4优先选CBC或GCM模式(需随机IV)
- 摘要增强:
- 密码存储应结合盐值(Salt)+多次哈希
5. 总结
本文完整实现了:
- SM4对称加密工具类(支持密钥生成/CBC模式加解密)
- SM3摘要工具类(支持字符串/文件摘要)
- SM2非对称加密工具类(密钥对生成/加解密)
- 详细对比了对称/非对称加密特性
📌 提示:生产环境建议使用国密合规的硬件加密机进行密钥管理。
如果觉得有帮助,请点赞收藏支持! 🔐