第1章:国密算法概述与Java国密SDK简介
聊国密之前,我想先问一句——你手头有项目被要求过“必须支持国密”吗?
我自己就碰过。前几年做政务系统对接,客户上来就说:“我们不认国际算法,只认国密。” 那时候我脑子里只有RSA和AES,差点没接住这活儿。
说白了,国密不是新的加密魔法。
它是中国国家密码管理局制定的一套商用密码算法标准。
SM2、SM3、SM4、SM9这些名字,你肯定见过。
1.1 为什么要有国密
你想想看,过去我们用的RSA、ECC、SHA-256,都是NIST(美国国家标准与技术研究院)定义的。万一哪天标准变动或限制出口,底层安全就悬了。
国密标准发布时间线
| 标准代号 | 算法名称 | 对标国际算法 | 发布年份 |
|---|---|---|---|
| GB/T 32918 | SM2 | RSA / ECDSA | 2016 |
| GB/T 32905 | SM3 | SHA-256 | 2016 |
| GB/T 32907 | SM4 | AES | 2016 |
| GM/T 0044 | SM9 | (基于标识的密码) | 2016 |
看懂这个表,你就能理解——国密不是凭空冒出来的。
每一套算法背后都有清晰的数学和国际对标逻辑。
我建议你先把这张表记心里,后续章节会反复用到。
1.2 国密核心算法——一条条拆开讲
SM2:非对称加密 & 数字签名
SM2基于椭圆曲线密码学(ECC)。
说白了就是,你有一对公私钥,公钥发给别人,私钥打死别泄露。
它比RSA牛逼在哪儿?
- 密钥更短,安全强度更高:SM2用256位密钥,安全性不低于RSA 2048位。
- 签名验证更快:证书签发效率明显提升。
- 支持密钥交换:双方不直接传密钥,通过SM2协商出会话密钥。
我曾经在项目中踩过一个坑——用SM2签名后忘记了做DER编码转换,结果对方证书解析失败。SM2签名结果的格式默认是(r, s)两个大数,你需要自己拼成DER结构传给验证端。
SM3:密码杂凑算法
SM3说白了就是国产版的SHA-256。
它的输出是256位(32字节),主要用于完整性校验和数字签名中的摘要生成。
实际业务中,我见过最频繁的用法:
- 用户密码加盐SM3后存库
- 文件上传时计算SM3哈希,防篡改
- 签名前先用SM3压缩明文
注意一点——SM3计算速度比SM2快得多,但它不能用来加密。记住这个区分。
SM4:对称分组加密算法
SM4对标的是AES。
密钥长度128位,分组长度128位。
我刚开始接触SM4时觉得跟AES没什么区别,直到动手写代码才发现——
SM4的S盒、密钥扩展算法都不一样,不能简单把AES库换成SM4就完事。
SM4主要工作模式
| 模式 | 说明 | 常见场景 |
|---|---|---|
| ECB | 电子密码本模式 | 简单块加密(不建议用于长数据) |
| CBC | 密码分组链接模式 | 数据报文加密(需要IV) |
| GCM | 伽罗瓦计数器模式 | 带认证的加密(同时防篡改) |
| CTR | 计数器模式 | 流式加密,支持并行计算 |
我个人的习惯:除非有特殊说明,所有新项目我都用SM4-GCM。自带完整性校验,省得你另算MAC。
SM9:基于标识的密码算法
这个稍微有点偏门,但重要。
SM9的特点是不需要证书。 用户的公钥直接就是邮箱、身份证号或手机号。
为什么会有这种需求?
你想想看,物联网里有几万个设备,每个设备配一张证书管理成本有多高。SM9省掉了CA系统,适合轻量级场景。
SM9目前在国内部分金融和政务系统中已开始试点,但商用实施案例较少。 如果你只是做常规Web服务,建议先搞定SM2 + SM3 + SM4。
1.3 国密 vs 国际算法——核心差异表
| 对比维度 | 国密 | 国际算法 |
|---|---|---|
| 标准化主体 | 中国国家密码管理局 | NIST / ISO |
| 非对称算法 | SM2(椭圆曲线) | RSA / ECDSA |
| 哈希算法 | SM3(256位) | SHA-256 |
| 对称加密 | SM4(128位分组) | AES(128/192/256位) |
| 证书体系 | 依赖SM2证书,遵循GMT 0015 | X.509证书 + PKI |
| Java库支持 | 需额外SDK(BC、HSM、自研) | JDK内置(JDK 8+) |
这张表我建议你截图保存。
每次跟非技术同事解释“为什么要换国密”时,直接甩这张表就够用。
1.4 Java国密SDK的整体架构
说了半天算法,代码怎么写?
Java里没有原生JDK支持国密,你需要一套SDK来提供封装。
市面上主流的实现方式:
- Bouncy Castle(BC)增强版:最常用,开源社区已经支持SM2/SM3/SM4,JDK Security Provider 模式。
- 华为/江南天安等厂商HSM SDK:硬件加密机对接,性能高但成本也高。
- 自研国密库:部分金融公司自研,一般不对外公开。
我在这门课里会核心讲解第1种——基于Bouncy Castle的Java国密SDK适配方式。原因很简单:免费、可落地、社区活跃。
1.5 一个简单的Hello国密——代码示例
给你看一个最基础的SM2密钥对生成,感受一下风格:
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.security.KeyPairGenerator;
import java.security.Security;
import java.security.KeyPair;
public class SM2Demo {
public static void main(String[] args) throws Exception {
// 注入BC Provider
Security.addProvider(new BouncyCastleProvider());
// 使用SM2算法生成密钥对
KeyPairGenerator gen = KeyPairGenerator.getInstance("SM2", "BC");
gen.initialize(256);
KeyPair kp = gen.generateKeyPair();
System.out.println("公钥: " + kp.getPublic());
System.out.println("私钥: " + kp.getPrivate());
// 这里可以直接用kp.getPublic()和kp.getPrivate()做签名/加密
}
}
看清楚——核心就两步:
1. 往Security里注册BouncyCastleProvider
2. 指定算法名“SM2”和Provider“BC”
代码就这么简单。但实际项目里踩的坑往往都在后面——证书格式、DER编码、密钥存储、加密模式选择。这些我会在后续章节一一展开。
1.6 本章知识结构图
下面这张SVG图帮你梳理本章的核心逻辑:
1.7 本章关键点速查
- 国密包含SM2(非对称/签名)、SM3(哈希)、SM4(对称加密)、SM9(标识密码)
- SM2基于椭圆曲线,密钥256位,安全强度对标RSA 2048
- SM3输出32字节,用于完整性校验和摘要
- SM4分组128位,推荐用GCM模式自带认证
- Java里做国密,最方便的方式是Bouncy Castle + Provider注入
- 后续章节会深入讲证书、数字信封、签名验签、性能调优