ECDSA与SHA256详解

我不介意人走茶凉,孤独好过念念不忘。无论是曾经的亲密,还是如今的疏离,最深的痛苦往往是对过去的执念

Posted by yishuifengxiao on 2026-05-08

1.2.840.10045.4.3.2ecdsa-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-256ECDSA 分别在什么时候起作用。

  1. 准备阶段:原始消息

    • 假设爱丽丝需要签署一条消息,例如 "release v2.0.0"。她拥有一个与她的公钥配对的私钥。
  2. 第一步:SHA-256 哈希(压缩信息)

    • 起作用的算法:SHA-256
    • 作用:爱丽丝首先对原始消息 "release v2.0.0" 应用 SHA-256 哈希算法。这个算法会将任意长度的消息,转换成一个固定长度(256位)的“指纹”,即消息摘要(Message Digest)。
    • 目的:这一步的目的是将待签名的数据压缩成一个固定大小的、独特且不可逆的摘要。这样做既能提高后续签名运算的效率,也能满足密码学安全需求。
  3. 第二步:ECDSA 签名(核心加密运算)

    • 起作用的算法:ECDSA
    • 作用:爱丽丝使用她的 私钥 和上一步生成的 SHA-256 消息摘要 作为输入,运行 ECDSA 签名算法。
    • 结果:ECDSA 算法会输出一对数字 (r, s),这就是该消息的数字签名
    • 关键点:ECDSA 算法本身不直接处理原始的大消息,而是处理其哈希值。为了安全,ECDSA 在生成签名时还会引入一个随机数(nonce),这使得即使对同一消息多次签名,生成的 (r, s) 对也可能不同。
  4. 最终输出

    • 爱丽丝将原始消息 "release v2.0.0" 连同计算出的签名 (r, s) 一起发送给鲍勃。

验证过程简述(SHA-256 和 ECDSA 再次配合)

当鲍勃收到消息和签名后,验证过程会再次用到这两个算法:

  1. SHA-256:鲍勃对收到的原始消息 "release v2.0.0" 使用相同的 SHA-256 算法,独立计算出一个消息摘要。
  2. 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) * QG 是椭圆曲线的基点)。

因为公钥 Q = d * G,经过数学代换后,这个计算结果必然等于 k * G。验证者只需要拿这个结果的 X 轴坐标去和签名里的 r 比对——如果相等,说明签名合法。

在这个过程中,验证者全程只做了代数运算,他不需要知道 k 具体是多少,只需要知道“存在一个未知的 k 能使得这个等式成立”即可。这类似于你不需要知道一把锁的具体内部弹簧结构,只要用正确的钥匙(公钥)能拧开(验证通过),就能确认锁芯(签名)是匹配的。

现实类比:密封的信封

想象一下:

  • 爱丽丝把一张写有随机数的纸条(随机数 k)放在一个特制的保险盒子里,然后锁上盒子。
  • 她把这个盒子(公钥 Q)发给鲍勃,但把纸条(k)销毁了。
  • 当爱丽丝签署文件时,她利用这个销毁掉的纸条对文件进行了特殊封装,生成了一串防伪码(签名 r, s)。
  • 鲍勃收到防伪码后,只需要拿爱丽丝给的盒子(公钥)去对准防伪码进行特定运算。如果运算结果严丝合缝(r 匹配),鲍勃就能确定:“爱丽丝一定在签署时拥有过那张纸条,否则她算不出这个防伪码。”

鲍勃不需要找到那张已经销毁的纸条,他只需要验证盒子和防伪码的数学匹配关系即可。


特别重要:随机数虽然对验证者隐藏,但对签名者是“致命弱点”

虽然验证者不知道随机数没问题,但签名者(爱丽丝)绝对不能重复使用这个随机数 k

  • 如果两次签名用了同一个随机数 k,由于两个消息的哈希值 z1z2 不同,攻击者可以通过两个签名的 s1s2 做减法,直接解方程消去 k 和椭圆曲线点,从而推导出爱丽丝的私钥 d
  • 这是历史上真实发生过的事故(如索尼 PS3 的私钥泄露,就是因为签名时随机数没有变化)。

所以,这个随机数 k 的角色是:对全世界(包括验证者)保密,但对自己(签名者)也必须每次唯一且不可预测。