2、签名算法基础(上):对称加密与非对称加密、哈希函数(MD5、SHA-256)、HMAC原理
聊签名服务,绕不开加密和哈希。很多新手一上来就纠结「到底用哪种算法」,其实没那么玄乎。我做了这么多年后端,总结下来就一句话:对称加密管传输,非对称加密管身份,哈希函数管完整性。咱们一个一个拆开说。
2.1 对称加密:一把钥匙开一把锁
对称加密,说白了就是加密和解密用同一把密钥。你想想看,就像你家里的大门,用一把钥匙锁上,也用同一把钥匙打开。简单、快,这是它的优点。
常见的对称加密算法有 AES、DES、3DES。现在业界主流是 AES-256,我个人习惯只要涉及敏感数据传输,优先选它。
核心特点:
- 加密速度快,适合大数据量
- 密钥长度短(128/192/256位)
- 最大痛点:密钥分发困难
我在项目中遇到过一个问题:两个微服务之间需要加密通信,密钥写死在配置文件里。结果运维不小心把配置库权限设成了公开,密钥直接裸奔。嗯,这里要注意——对称加密的密钥管理,比算法本身难十倍。
| 算法 | 密钥长度 | 安全性 | 速度 |
|---|---|---|---|
| DES | 56位 | 已淘汰 | 快 |
| 3DES | 112/168位 | 中等 | 慢 |
| AES | 128/192/256位 | 高 | 快 |
实战建议:签名服务内部通信,我推荐用 AES-256-GCM 模式。它自带认证标签,能防篡改,省掉你额外算 HMAC 的麻烦。
2.2 非对称加密:公钥私钥两把锁
非对称加密就很有意思了。它有一对密钥:公钥公开,私钥自留。公钥加密的数据只有私钥能解,私钥签名的数据只有公钥能验。这解决了对称加密「密钥分发」的痛点。
常见的算法有 RSA、ECC(椭圆曲线)。RSA 最经典,但密钥越长性能越差。ECC 用更短的密钥达到同等安全强度,现在越来越流行。
核心应用场景:
- 加密通信:客户端用服务器公钥加密数据,只有服务器私钥能解
- 数字签名:服务器用私钥签名,客户端用公钥验签
我曾经踩过一个坑:用 RSA 加密大文件,结果直接报错。为什么?因为 RSA 有长度限制,1024位密钥最多加密117字节。所以实际项目中,非对称加密通常只用来加密对称密钥,真正的数据用 AES 加密。这叫「混合加密」,HTTPS 就是这么干的。
| 对比项 | 对称加密 | 非对称加密 |
|---|---|---|
| 密钥数量 | 1个 | 2个(公钥+私钥) |
| 速度 | 快 | 慢(慢100-1000倍) |
| 密钥分发 | 困难 | 容易(公钥可公开) |
| 典型算法 | AES | RSA、ECC |
2.3 哈希函数:数据的指纹
哈希函数,你可以把它理解成给数据算一个「指纹」。不管输入多大,输出固定长度。而且有个重要特性:不可逆——从哈希值推不出原始数据。
签名服务里,哈希函数主要用来做两件事:
- 数据完整性校验:对比哈希值就知道数据有没有被改过
- 签名预处理:先哈希再签名,提高效率
MD5:老将退役
MD5 输出128位(32个十六进制字符)。以前很流行,但现在已经被攻破了。2004年就有学者找到了碰撞——两个不同文件算出相同 MD5。我建议:新系统绝对不要用 MD5,除非你只是做文件去重这种非安全场景。
避坑指南:我曾经接手过一个老项目,用 MD5 做支付签名。结果被黑客伪造了请求,直接导致线上事故。从那以后,我对 MD5 彻底拉黑。
SHA-256:当前主力
SHA-256 输出256位(64个十六进制字符),属于 SHA-2 家族。目前没有已知的有效碰撞攻击,是签名服务的标配。
// 一个简单的 SHA-256 示例(伪代码)
输入: "hello"
输出: "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"
// 哪怕只改一个字符
输入: "hellp"
输出: "6f8db599de30fab0b6f12c8b5b5b1c8f1c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c"
你看,输入只差一个字母,输出完全不一样。这就是哈希函数的「雪崩效应」。
2.4 HMAC:带密钥的哈希
HMAC(Hash-based Message Authentication Code)是哈希函数的进阶版。它给哈希加了一把「密钥」,只有知道密钥的人才能验证消息的完整性。
普通哈希有个问题:攻击者可以同时篡改数据和哈希值。但 HMAC 不一样,它把密钥混进哈希计算,攻击者没有密钥就伪造不了合法的 HMAC。
HMAC 的计算过程(简化版):
- 把密钥填充到哈希块长度
- 密钥与 ipad(内部填充)异或,再拼接消息,做第一次哈希
- 密钥与 opad(外部填充)异或,再拼接第一次哈希结果,做第二次哈希
// HMAC-SHA256 示例(伪代码)
HMAC-SHA256(key, message) =
SHA256((key ⊕ opad) || SHA256((key ⊕ ipad) || message))
// 实际使用
key = "my-secret-key"
message = "amount=100×tamp=1700000000"
result = HMAC-SHA256(key, message)
// 输出: "a1b2c3d4..."
我个人的习惯是:API 签名首选 HMAC-SHA256。它比直接 RSA 签名快得多,而且密钥管理比对称加密简单。很多大厂的开放平台,比如阿里云、腾讯云,用的就是 HMAC 签名方案。
2.5 知识体系总览
下面这张图把本章的核心逻辑串起来了。你看一遍,应该能对签名算法的全貌有个清晰认识。
2.6 实战选型建议
说了这么多,到底怎么选?我总结了一个简单的决策树:
- 要加密大量数据? → 用 AES-256-GCM
- 要安全分发密钥? → 用 RSA/ECC 做密钥交换
- 要校验数据完整性? → 用 SHA-256
- 要做 API 签名? → 用 HMAC-SHA256
一个小技巧:HMAC 的密钥不要直接用字符串。我习惯先对密钥做一次 SHA-256 哈希,再用哈希结果做 HMAC 密钥。这样能保证密钥长度正好是 32 字节,避免填充带来的性能损耗。
好了,这一章的基础知识就到这里。你把这些概念吃透了,后面讲具体签名流程的时候,理解起来会轻松很多。