数字签名(Digital Signature)是用 私钥 为消息生成可验证证明、再用 公钥 验证消息来源和完整性的 公钥密码学 机制。
核心问题
数字签名解决的是“接收方如何确认这段数据确实由某个 私钥 持有者授权,并且传输或存储过程中没有被篡改”的问题。它关注真实性和完整性,不提供机密性。
核心机制
典型流程是:
可抽象为:
常见算法包括 RSA-PSS、ECDSA、EdDSA 和 Ed25519。签名算法通常需要把上下文、算法标识、时间戳或业务字段纳入签名输入,避免签名被挪用到另一个语义场景。
以 ECDSA P-256 为例,私钥 d 是一个 32 字节左右的大整数,公钥是曲线点:
Q = dG这里 G 是公开基点,dG 是 椭圆曲线标量乘法,不是普通数字乘法。签名由两个大整数组成:
signature = (r, s)签名过程可以写成:
e = H(M) # 消息摘要
k = 每次签名的一次性数
R = kG = (x1, y1)
r = x1 mod n
s = k^-1 * (e + r*d) mod n验签方没有 d 和 k,但有公钥 Q。它通过 (r, s)、消息摘要和 Q 计算:
w = s^-1 mod n
u1 = e*w mod n
u2 = r*w mod n
X = u1G + u2Q如果 X 的横坐标取模后等于 r,验签通过。合法签名能通过,是因为 Q = dG,代入后 u1G + u2Q 会化简回签名时的 kG。这解释了为什么“私钥能签名,公钥能验签”,但公钥不能反推出私钥。
工程用途
- 证书体系:证书颁发机构用签名把身份和 公钥 绑定到 数字证书。
- 软件发布:包管理器、安装包、固件和容器镜像签名。
- Git 与提交验证:证明提交或标签来自某个密钥持有者。
- 区块链交易:私钥 签名表达资产转移授权。
- 离线授权:设备或客户端只内置 公钥,无法伪造平台 签发 的授权材料。
边界与常见坑
- 签名不是加密:签名后的内容仍然可能是明文,旁观者可以读取。
- 能验签不等于可信:还要判断 公钥 是否可信、数字证书 是否有效、密钥是否撤销。
- 签名只覆盖被签名的字节:未纳入签名的字段仍可被篡改。
- 规范化很重要:JSON 字段顺序、空白、编码和数字表示不同,可能导致验签失败或语义绕过。
- 不要混用密钥用途:签名密钥、加密密钥、密钥交换密钥最好分离。
- 随机数错误会泄露私钥:部分签名算法如 ECDSA 对 nonce 质量非常敏感,重复使用一次性数
k可能直接推导出私钥。