深色模式
关于数字签名
概述
数字签名解决的,不是“把内容藏起来”,而是“证明这份内容是谁发的,以及中途有没有被改过”。
这和加密很容易混。加密关注保密性,签名关注完整性和身份认证。两者经常同时出现,但职责完全不同。把它们说成一回事,接口设计和安全评审通常都会开始跑偏。
数字签名想证明什么
数字签名主要想证明两件事:
- 内容没有被篡改
- 内容确实来自某个持有私钥的人
如果签名能通过,说明数据和签名是一套对得上的东西;如果签名失败,常见原因只有两类:
- 内容被改过
- 签名者并不拥有对应私钥
签名和验签的基本流程
一个典型流程可以简化成这样:
- 发送方准备原始数据。
- 先对数据做散列,得到摘要。
- 用自己的私钥对摘要进行签名。
- 把原始数据和签名一起发出去。
- 接收方收到后,先对原始数据重新计算摘要。
- 再用发送方公钥验证签名。
如果两边结果一致,就说明验签通过。
这里“先散列再签名”很常见,因为直接对大块原文做签名既不高效,也不符合多数算法的典型用法。
为什么签名通常要配合公钥体系
数字签名通常建立在非对称密码体系上,也就是一对密钥:
- 私钥:签名者自己保管
- 公钥:分发给验签者使用
这套设计的好处是,很多人可以拿着同一把公钥验签,但只有持有私钥的人才能生成正确签名。
常见算法包括:
RSAECDSAEd25519SM2
数字签名和加密的区别
这两个概念必须拆开看。
| 能力 | 目标 | 常见操作 |
|---|---|---|
| 加密 | 防止别人看到内容 | 公钥加密 / 私钥解密,或对称加密 |
| 数字签名 | 证明身份和防篡改 | 私钥签名 / 公钥验签 |
一个常见误区是:“既然私钥能签名,那是不是也等于私钥加密?”在概念上最好不要这样说。虽然某些教材会拿“公钥加密、私钥解密”和“私钥签名、公钥验证”做对照帮助理解,但工程上应把签名当成独立能力来看。
数字签名和散列的关系
散列函数为签名提供摘要,签名算法为摘要提供身份认证。
如果只有散列,没有签名:
- 谁都能重新算一遍摘要
- 无法证明是谁发的
如果只有签名概念,不先做散列:
- 处理大数据成本高
- 也不符合多数算法的常见使用方式
因此两者经常一起出现,但不要把它们混成一个词。
数字证书为什么会出现
到这里会冒出一个现实问题:验签需要公钥,那这个公钥本身怎么相信?
这就是数字证书存在的原因。数字证书本质上是“某个主体的公钥,加上一组身份信息,再由可信机构签名确认”。这样接收方不只是拿到一个裸公钥,还能验证它是否来自受信任的链路。
所以关系可以这样看:
- 数字签名:证明内容和私钥持有者有关
- 数字证书:证明某个公钥值不值得信任
常见使用场景
HTTPS
TLS 握手里会用证书和签名机制来验证服务端身份,避免客户端把流量送给冒充者。
软件分发
安装包、驱动、移动应用、系统更新包常会带签名。验签通过,才说明包来自发布方并且没有被替换。
接口签名
开放平台常说的“请求签名”,有些是非对称签名,有些其实是 HMAC。名字相似,机制不同,需要看文档细节。
什么时候验签失败
最常见的原因有:
- 原文参与签名的字段顺序变了
- 参与签名的编码方式不一致
- 公钥和私钥不是一对
- 签名算法或参数不一致
- 中途内容被篡改
很多“签名错误”并不是密码学本身出问题,而是实现双方对输入字符串的拼接规则没有对齐。
