密码算法基础:对称加密、非对称加密、哈希算法、数字签名原理

做密码SDK兼容测试,最先要搞清楚的不是测试用例怎么写,而是算法本身到底在干什么。你想想看,如果连加密和签名的区别都理不清,测试结果再漂亮也没用。

我自己带团队做兼容测试那几年,踩得最多的坑就是把数字签名和加密搞混——有人拿签名算法去加密数据,结果解密全失败,还以为是SDK的bug。所以这一节,我们把四个最基础的密码算法掰开揉碎了聊。

核心一句话:对称加密管效率,非对称加密管安全分发,哈希算法管完整性,数字签名管身份+完整性。
密码算法基础核心结构 对称加密 AES / DES / SM4 非对称加密 RSA / ECC / SM2 哈希算法 SHA-256 / SM3 / MD5 数字签名 私钥签名 ➔ 公钥验签 底层 = 哈希 + 非对称加密 速度最快 密钥分发难 签名 = 哈希摘要 + 私钥加密 💡 实测提醒:签名算法用的哈希不一定和单独哈希版本的输出长度一致,比如 RSA-PSS 内部哈希可以配置。

对称加密:又快又简单,但密钥怎么给?

对称加密说白了就是一把钥匙开一把锁。加密和解密用同一个密钥。我平时调AES接口多了,最常用的模式是GCM——自带认证标签,防篡改。

主流算法:AES(128/192/256)、SM4(国密)、DES(太弱,别用)、ChaCha20(移动端常见)。

// 用OpenSSL做AES-256-GCM加密(伪命令行)
openssl enc -aes-256-gcm -K 00112233445566778899aabbccddeeff -iv 010203040506 -in plain.txt -out cipher.bin
我的经验:测试时优先关注密钥长度和模式。曾经遇到一个SDK只支持ECB模式,我要求在GCM模式测试,对方说“ECB也一样安全”……幸好我坚持让他改,后来安全审计正好卡了ECB的漏洞。

非对称加密:公钥随便给,私钥藏好

非对称加密有两把钥匙:公钥加密,私钥解密。反之也可以(私钥签名,公钥验签)。实际项目中你几乎不会直接用公钥加密大文件——太慢了。我习惯拿它做密钥交换:先用非对称加密传一个临时对称密钥,后续会话用对称加密。

常见算法:RSA(2048位起)、ECC(推荐256位)、SM2。

对比项对称加密非对称加密
密钥数量1个2个(公钥+私钥)
速度快(硬件加速)慢(数学运算)
典型用途大量数据加密密钥协商、数字签名
密钥分发需要安全通道公钥可公开
安全强度密钥长度决定数学困难问题决定
⚠️ 注意:我曾经用RSA 1024位做了个小工具,结果一年后就被破解了。现在通用规范起步就是2048位,国密SM2默认推荐256位椭圆曲线。

哈希算法:单向不可逆,雪崩效应

哈希不是加密,它没有密钥。输入任意长度,输出固定长度(比如SHA-256输出32字节)。一个微小的变化——哪怕只改一个比特——输出也会天翻地覆,这就是雪崩效应。

你在SDK里看到哈希主要用在:密码存储(加盐)、文件校验、消息摘要生成。我个人习惯,做兼容测试时一定检查输出长度和大小写——很多Java和C的哈希输出默认小写,但有些SDK输出大写,结果校验对不上。

echo -n "Hello" | sha256sum
# 输出:185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969

数字签名:哈希 + 非对称的合体技

数字签名解决两个问题:谁发的?改了没?发信人用私钥对消息的哈希值加密,接收方用公钥解密哈希值,再自己算一遍消息哈希,两个一致就验证通过。

嗯,这里要注意:签名算法里用的哈希不一定和独立哈希算法的输出格式完全相同。比如RSA-PSS内部会把哈希值填充后再运算,如果你直接拿来比对原始哈希值,大概率会失败。

测试关键点:签名验证时,确认SDK接受的签名格式(DER? P1363?)、哈希算法指定方式(是否允许协商?)、以及是否强制要求摘要填充。

我遇到过最典型的坑:某国产SDK用SM2+SM3做签名,文档写的是SM2signature,但实际返回的签名是纯R/S拼接(P1363格式),而验签接口却要求DER编码。这种问题不靠原理分析,光靠黑盒测试根本找不到。

四种算法各司其事,但实际产品里常常组合使用。比如HTTPS:握手阶段用RSA/ECC交换临时对称密钥,后续用AES加密数据,再用HMAC(基于哈希)做消息认证。做兼容测试时,理清楚算法之间的依赖关系,能省下一大半排查时间。