Java实现国密算法 SM2 /SM3 /SM4(基于 BouncyCastle)
密码学算法分类指南[
国密算法全解析
环境要求:
- JDK 17
- Maven 3
- BouncyCastle(1.78 )
1. Maven 依赖配置
在 pom.xml 中添加如下依赖:
<!-- 1.78 -->
<dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk18on</artifactId><version>1.78</version>
</dependency>
2. 基础设置:注册 BouncyCastle 提供者
初始化加密环境,必须提前注册 BouncyCastle,否则密钥从数据库或者配置加载会报错。如果生成就直接使用那不会报错。
import org.bouncycastle.jce.provider.BouncyCastleProvider;import java.security.Security;
import java.util.Objects;/**** * @date 2025/11/5**/
public class SmBaseUtils {// 推荐 12 字节 IV(96位)public static final int IV_LENGTH = 12;// 128位 = 16字节public static final int KEY_LENGTH = 16;// GCM认证标签长度(位)public static final int GCM_TAG_LENGTH = 128;static {// 注册 BouncyCastle 提供者if (Objects.isNull(Security.getProvider(BouncyCastleProvider.PROVIDER_NAME))) {Security.addProvider(new BouncyCastleProvider());}}
}
3. SM2 密钥对对象
用于保存生成的公钥和私钥。
/**** * @date 2025/11/5**/
public class Sm2KeyPair {private final String publicKey;private final String privateKey;public Sm2KeyPair(final String publicKey, final String privateKey) {this.publicKey = publicKey;this.privateKey = privateKey;}public String getPublicKey() {return publicKey;}public String getPrivateKey() {return privateKey;}
}
4. 密钥生成工具类
支持 SM2 非对称密钥和 SM4 对称密钥的生成、校验。
import com.example.sm.dto.Sm2KeyPair;import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;
import java.security.spec.ECGenParameterSpec;
import java.util.Base64;
import java.util.Objects;/**** * @date 2025/11/5**/
public class SmKeyGenUtils extends SmBaseUtils {/*** 生成 SM4 密钥(对称加密).** @return 密钥*/public static String generateSM4Key(int length) {byte[] key = new byte[length];new SecureRandom().nextBytes(key);return Base64.getEncoder().encodeToString(key);// return Hex.toHexString(key);}/*** 生成 SM2 密钥对(非对称加密).** @return 包含公钥和私钥的对象*/public static Sm2KeyPair generateSM2KeyPair() {try {KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC", "BC");keyPairGenerator.initialize(new ECGenParameterSpec("sm2p256v1"), new SecureRandom());KeyPair keyPair = keyPairGenerator.generateKeyPair();String publicKey = Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded());String privateKey = Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded());return new Sm2KeyPair(publicKey, privateKey);} catch (Exception e) {throw new RuntimeException("Failed to generate SM2 key pair", e);}}/*** 校验 SM4 密钥合法性(必须是 32 位十六进制).** @param key key* @return 校验sm4key是否有效*/public static boolean isValidSM4KeyHex(final String key) {return Objects.nonNull(key) && key.matches("^[0-9a-fA-F]{32}$");}/*** 校验 SM4 密钥合法性(Base64 编码,必须解码后为 16 字节).** @param key Base64 编码的密钥* @param length 秘钥长度* @return 是否为合法的 SM4 密钥*/public static boolean isValidSM4Key(final String key,final int length) {if (Objects.isNull(key)) {return false;}try {byte[] decodedKey = Base64.getDecoder().decode(key);return decodedKey.length == length;} catch (IllegalArgumentException e) {return false;}}
}
5. 加解密与摘要工具类
包含 SM2/SM3/SM4/AES-GCM 的加解密实现。支持 CBC 模式、GCM 模式、AEAD 等。
支持功能:
- SM2 公钥加密 / 私钥解密
- SM3 摘要计算
- SM4 对称加密(支持 CBC 和 GCM)
- AES-GCM 加密解密
- Base64 编码
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.digests.SM3Digest;
