1.2.840.10045.4.3.2 是 ecdsa-with-SHA256 算法的对象标识符(OID)。它定义了一种利用椭圆曲线密码学(ECC)生成和验证数字签名的标准方法。
简单来说,这个OID代表了一个“算法组合”:
- 核心签名算法:ECDSA (Elliptic Curve Digital Signature Algorithm,椭圆曲线数字签名算法)。
- 配套哈希算法:SHA-256 (Secure Hash Algorithm 256-bit,安全哈希算法)。
该算法的技术细节由 IETF RFC 5758 定义。它在实践中的一个常见别名是 ES256。
工作流程:SHA-256 和 ECDSA 如何各司其职
为了理解这两个算法如何协同工作,可以将整个过程分为签名和验证两个阶段。下面以 签名生成 为例,说明 SHA-256 和 ECDSA 分别在什么时候起作用。
准备阶段:原始消息
- 假设爱丽丝需要签署一条消息,例如
"release v2.0.0"。她拥有一个与她的公钥配对的私钥。
- 假设爱丽丝需要签署一条消息,例如
第一步:SHA-256 哈希(压缩信息)
- 起作用的算法:SHA-256
- 作用:爱丽丝首先对原始消息
"release v2.0.0"应用 SHA-256 哈希算法。这个算法会将任意长度的消息,转换成一个固定长度(256位)的“指纹”,即消息摘要(Message Digest)。 - 目的:这一步的目的是将待签名的数据压缩成一个固定大小的、独特且不可逆的摘要。这样做既能提高后续签名运算的效率,也能满足密码学安全需求。
第二步:ECDSA 签名(核心加密运算)
- 起作用的算法:ECDSA
- 作用:爱丽丝使用她的 私钥 和上一步生成的 SHA-256 消息摘要 作为输入,运行 ECDSA 签名算法。
- 结果:ECDSA 算法会输出一对数字
(r, s),这就是该消息的数字签名。 - 关键点:ECDSA 算法本身不直接处理原始的大消息,而是处理其哈希值。为了安全,ECDSA 在生成签名时还会引入一个随机数(nonce),这使得即使对同一消息多次签名,生成的
(r, s)对也可能不同。
最终输出
- 爱丽丝将原始消息
"release v2.0.0"连同计算出的签名(r, s)一起发送给鲍勃。
- 爱丽丝将原始消息
验证过程简述(SHA-256 和 ECDSA 再次配合)
当鲍勃收到消息和签名后,验证过程会再次用到这两个算法:
- SHA-256:鲍勃对收到的原始消息
"release v2.0.0"使用相同的 SHA-256 算法,独立计算出一个消息摘要。 - ECDSA:鲍勃使用爱丽丝的 公钥、他计算出的消息摘要,以及收到的签名
(r, s),作为输入运行 ECDSA 验证算法。该算法会返回“有效”或“无效”的结果,从而确认消息是否由爱丽丝签署且未被篡改。
| 阶段 | 起作用的算法 | 核心任务 |
|---|---|---|
| 签名准备 | SHA-256 | 将任意长度的原始消息,压缩成一个固定长度(256位)的消息摘要。 |
| 签名生成 | ECDSA | 使用私钥,对SHA-256生成的消息摘要进行签名,输出签名值 (r, s)。 |
| 验证准备 | SHA-256 | 验证方对收到的原始消息,再次使用SHA-256生成消息摘要。 |
| 签名验证 | ECDSA | 使用公钥,对SHA-256生成的消息摘要和收到的签名进行验证。 |
因此,ecdsa-with-SHA256 是一个两步走的流程:先用 SHA-256 将数据“浓缩”,再用 ECDSA 对“浓缩”后的结果进行签名或验证。
签名时使用了随机数(nonce),验证过程中不知道这个随机数会有问题吗
完全不会有问题,反而这正是公钥密码学的精妙设计所在。
验证者不需要也不应该知道这个随机数(nonce)。因为 ECDSA 的数学结构保证了:只要用公钥、消息哈希和签名本身,就能在不暴露随机数的情况下,逆向推导出“这个随机数存在且合法”这一事实。
数学原理:随机数被“锁”在了签名里
ECDSA 生成的签名是一对整数 (r, s)。其中:
r:是由随机数k在椭圆曲线上计算出的一个点的 X 轴坐标。s:是通过一个数学公式计算出来的:s = (z + r * d) / k(其中z是 SHA-256 哈希值,d是私钥)。
验证过程是一个数学恒等式。验证者将公钥 Q、哈希 z 和签名 (r, s) 代入椭圆曲线方程,计算 (z/s) * G + (r/s) * Q(G 是椭圆曲线的基点)。
因为公钥 Q = d * G,经过数学代换后,这个计算结果必然等于 k * G。验证者只需要拿这个结果的 X 轴坐标去和签名里的 r 比对——如果相等,说明签名合法。
在这个过程中,验证者全程只做了代数运算,他不需要知道 k 具体是多少,只需要知道“存在一个未知的 k 能使得这个等式成立”即可。这类似于你不需要知道一把锁的具体内部弹簧结构,只要用正确的钥匙(公钥)能拧开(验证通过),就能确认锁芯(签名)是匹配的。
现实类比:密封的信封
想象一下:
- 爱丽丝把一张写有随机数的纸条(随机数 k)放在一个特制的保险盒子里,然后锁上盒子。
- 她把这个盒子(公钥 Q)发给鲍勃,但把纸条(k)销毁了。
- 当爱丽丝签署文件时,她利用这个销毁掉的纸条对文件进行了特殊封装,生成了一串防伪码(签名 r, s)。
- 鲍勃收到防伪码后,只需要拿爱丽丝给的盒子(公钥)去对准防伪码进行特定运算。如果运算结果严丝合缝(
r匹配),鲍勃就能确定:“爱丽丝一定在签署时拥有过那张纸条,否则她算不出这个防伪码。”
鲍勃不需要找到那张已经销毁的纸条,他只需要验证盒子和防伪码的数学匹配关系即可。
特别重要:随机数虽然对验证者隐藏,但对签名者是“致命弱点”
虽然验证者不知道随机数没问题,但签名者(爱丽丝)绝对不能重复使用这个随机数 k。
- 如果两次签名用了同一个随机数
k,由于两个消息的哈希值z1和z2不同,攻击者可以通过两个签名的s1和s2做减法,直接解方程消去k和椭圆曲线点,从而推导出爱丽丝的私钥d。 - 这是历史上真实发生过的事故(如索尼 PS3 的私钥泄露,就是因为签名时随机数没有变化)。
所以,这个随机数 k 的角色是:对全世界(包括验证者)保密,但对自己(签名者)也必须每次唯一且不可预测。