密码算法基础:对称加密、非对称加密、哈希算法、数字签名原理
做密码SDK兼容测试,最先要搞清楚的不是测试用例怎么写,而是算法本身到底在干什么。你想想看,如果连加密和签名的区别都理不清,测试结果再漂亮也没用。
我自己带团队做兼容测试那几年,踩得最多的坑就是把数字签名和加密搞混——有人拿签名算法去加密数据,结果解密全失败,还以为是SDK的bug。所以这一节,我们把四个最基础的密码算法掰开揉碎了聊。
对称加密:又快又简单,但密钥怎么给?
对称加密说白了就是一把钥匙开一把锁。加密和解密用同一个密钥。我平时调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
非对称加密:公钥随便给,私钥藏好
非对称加密有两把钥匙:公钥加密,私钥解密。反之也可以(私钥签名,公钥验签)。实际项目中你几乎不会直接用公钥加密大文件——太慢了。我习惯拿它做密钥交换:先用非对称加密传一个临时对称密钥,后续会话用对称加密。
常见算法:RSA(2048位起)、ECC(推荐256位)、SM2。
| 对比项 | 对称加密 | 非对称加密 |
|---|---|---|
| 密钥数量 | 1个 | 2个(公钥+私钥) |
| 速度 | 快(硬件加速) | 慢(数学运算) |
| 典型用途 | 大量数据加密 | 密钥协商、数字签名 |
| 密钥分发 | 需要安全通道 | 公钥可公开 |
| 安全强度 | 密钥长度决定 | 数学困难问题决定 |
哈希算法:单向不可逆,雪崩效应
哈希不是加密,它没有密钥。输入任意长度,输出固定长度(比如SHA-256输出32字节)。一个微小的变化——哪怕只改一个比特——输出也会天翻地覆,这就是雪崩效应。
你在SDK里看到哈希主要用在:密码存储(加盐)、文件校验、消息摘要生成。我个人习惯,做兼容测试时一定检查输出长度和大小写——很多Java和C的哈希输出默认小写,但有些SDK输出大写,结果校验对不上。
echo -n "Hello" | sha256sum
# 输出:185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969
数字签名:哈希 + 非对称的合体技
数字签名解决两个问题:谁发的?改了没?发信人用私钥对消息的哈希值加密,接收方用公钥解密哈希值,再自己算一遍消息哈希,两个一致就验证通过。
嗯,这里要注意:签名算法里用的哈希不一定和独立哈希算法的输出格式完全相同。比如RSA-PSS内部会把哈希值填充后再运算,如果你直接拿来比对原始哈希值,大概率会失败。
我遇到过最典型的坑:某国产SDK用SM2+SM3做签名,文档写的是SM2signature,但实际返回的签名是纯R/S拼接(P1363格式),而验签接口却要求DER编码。这种问题不靠原理分析,光靠黑盒测试根本找不到。
四种算法各司其事,但实际产品里常常组合使用。比如HTTPS:握手阶段用RSA/ECC交换临时对称密钥,后续用AES加密数据,再用HMAC(基于哈希)做消息认证。做兼容测试时,理清楚算法之间的依赖关系,能省下一大半排查时间。