基础密码学回顾:对称加密、非对称加密、哈希、数字签名

做加密SDK审计,绕不开这几个老朋友。我见过不少开发者,接口调了半天,结果连密钥用多大、模式选错都没意识到。说白了,基础不牢,审计就是个筛子。所以这一章,我们把对称加密、非对称加密、哈希和数字签名快速过一遍,重点放在它们在实际集成时容易踩的坑上。

对称加密:AES 与 SM4

对称加密,顾名思义,加密和解密用同一把钥匙。速度快,适合大量数据的加解密。标准接口里最常见的是 AES,国密则用 SM4。我在一个跨境支付项目中,就是被要求同时支持这两套算法。

核心要点:密钥长度、工作模式、IV 管理、填充方式。
参数AESSM4
密钥长度128 / 192 / 256 bits128 bits(固定)
分组大小128 bits128 bits
常见模式ECB, CBC, CTR, GCMECB, CBC, CTR, GCM(SM4-GCM 国标扩展)
填充PKCS7(CBC/ECB 必须)同左

这里重点讲模式。ECB 模式——千万别在生产环境用,同一明文块会得到相同密文块,泄露模式信息。我早年做过一个安全加固项目,对方的 SDK 默认用 ECB,我直接让他们全改成 GCM。为什么?GCM 自带认证,相当于加密 + 完整性校验,一步到位。

避坑:IV(初始化向量)必须随机生成,且每次加密用不同的值。我见过有人写死 IV = "0000000000000000",安全隐患极大。审计时一定会查这个。

非对称加密:RSA 与 SM2

非对称加密使用密钥对——公钥加密,私钥解密。主要用于密钥协商、数字签名和少量数据加密。RSA 是老牌选手,SM2 则是国密局基于椭圆曲线(ECC)的产物。

对比项RSASM2
密钥长度1024/2048/4096 bits256 bits(曲线长度)
安全强度2048 bits ≈ 112 bits 安全256 bits ≈ 128 bits 安全
性能慢(特别是私钥操作)快(同安全强度下约 5-10 倍)
主要用途加密小数据、数字签名加密、签名、密钥交换

我习惯在审计集成时优先推荐 SM2,原因很简单:密钥更短,性能更高,而且国产合规。但 RSA 在存量系统里仍然广泛存在,所以两套都得会。

个人经验:有一次接入某 SDK,对方返回的 SM2 公钥是 PEM 格式的 base64 编码,可内部接口却要求原始点格式(未压缩公钥)。不得不走一遍格式转换。建议在接口定义时统一使用 DER 编码,便于跨平台解析。

哈希:SHA256 与 SM3

哈希函数把任意长度的数据变成固定长度的摘要。不可逆、抗碰撞。SHA256 是国际标准,SM3 是国标。两者在审计接口中主要用于:完整性校验、密钥派生、消息认证码(HMAC)的基础。

算法输出长度安全强度使用场景
SHA256256 bits128 bits通用完整性校验
SM3256 bits128 bits国密标准,合规要求

你想想看,如果通信双方验证数据完整性,只传一个哈希值,中途被篡改怎么办?所以审计接口通常要求用 HMAC,也就是带密钥的哈希。我曾经在审计中发现一个系统直接用 SHA256 裸哈希做校验——攻击者只要能改数据就能重算哈希,完全没防护。后来改成了 HMAC-SM3。

注意:不要用明文保存用户密码的哈希。黑客拿到哈希表还是能撞库。正确的做法是用密码哈希函数(如 bcrypt、scrypt)或至少加随机盐。这一点审计接口里的密钥派生流程也类似,一定要引入随机盐。

数字签名

数字签名结合了哈希和非对称加密。流程很简单:发送方对消息做哈希,再用私钥签名;接收方用公钥验签。这样既能确认来源,又能防止篡改。

在审计接口里,常见的签名算法有 RSA-SHA256、SM2-SM3。前者是 RSA 私钥签名 + SHA256 哈希,后者是 SM2 私钥签名 + SM3 哈希。

一个常见套路:
  1. 对请求体按字典序拼接参数(如 a=1&b=2)
  2. 对整个字符串做哈希(SHA256 或 SM3)
  3. 用私钥签名得到签名值
  4. 接收方同样拼接、哈希、用公钥验签

我个人体会,签名最容易出错的地方是参数拼接顺序和空值处理。比如某个字段值为空,要不要拼进去?不同 SDK 理解不同。审计时必须明确规范,否则两端对不上签名。

// 伪代码示例:SM2 签名
byte[] digest = sm3Hash(message);
byte[] signature = sm2Sign(privateKey, digest);
// 接收方
byte[] digest = sm3Hash(message);
boolean ok = sm2Verify(publicKey, digest, signature);
基础密码学知识体系(审计集成视角) 密码学原语 对称加密 AES-128/256 SM4-128 模式:GCM > CBC > ECB 非对称加密 RSA-2048 SM2(ECC) 用途:加密 / 签名 哈希函数 SHA-256 SM3 输出:256 bits 数字签名(签名/验签)

看完这张图你就明白了,数字签名不是独立的新算法,而是把哈希和非对称加密组合在了一起。审计的时候,你需要检查每一步的实现是否正确:哈希算法是否合规、密钥管理是否有漏洞、签名拼接规则是否一致。

我的建议:做集成测试时,先跑一个已知的签名向量(比如国家密码管理局发布的 SM2 签名测试数据),验证 SDK 输出是否一致。这一步能过滤掉大部分底层实现问题。