You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

python-ecdsa生成的ECDSA签名长度是否符合预期?

为什么python-ecdsa生成的签名是64字节,而Bitcoin Wiki说71-73字节?

嘿,这个差异完全是因为签名格式不同导致的,咱们把这事掰明白:

1. python-ecdsa默认输出的是「原始ECDSA签名」

你用private_key.sign(b'message')得到的64字节签名,是最基础的ECDSA签名形式:它直接把签名里的两个核心整数r和s各以32字节的形式拼接在一起(因为Secp256k1的阶是256位,刚好对应32字节),所以总长度就是32+32=64字节。这是库的默认输出格式,完全符合ECDSA的数学定义,但不是比特币网络实际使用的格式。

2. Bitcoin Wiki提到的是「DER编码后的ECDSA签名」

比特币系统里用的签名是经过DER(Distinguished Encoding Rules)编码的,这是一种ASN.1标准的编码格式,目的是让签名结构更明确、能被不同系统解析。DER编码会给r和s加上额外的标识信息,比如:

  • 开头的0x30标记这是一个序列
  • 后续字节表示整个序列的总长度
  • 分别给r和s加上类型标识(0x02)、长度标识
  • 如果r或s的最高位是1,还会额外补一个0x00来避免被解析成负数,这就导致r或s的长度可能变成33字节

这些额外的编码字节加起来,就使得DER签名的总长度在71-73字节之间浮动(取决于r和s是否需要补0)。

3. 如何用python-ecdsa生成比特币兼容的DER签名?

你只需要把原始签名转换成DER格式就行,有两种简单的方法:

方法一:从原始签名编码成DER

from ecdsa import SigningKey, SECP256k1, util

private_key = SigningKey.generate(curve=SECP256k1)
# 生成原始64字节签名
raw_sig = private_key.sign(b'message')
# 拆分r和s,编码成DER格式
der_sig = util.sigencode_der(raw_sig[:32], raw_sig[32:], SECP256k1.order)
print(f"DER签名长度: {len(der_sig)}")  # 输出71-73之间的数值

方法二:直接生成DER格式签名

用sign_deterministic方法并指定编码方式(推荐,因为确定性签名更符合比特币的规范):

from ecdsa import SigningKey, SECP256k1, util

private_key = SigningKey.generate(curve=SECP256k1)
# 直接生成DER编码的签名
der_sig = private_key.sign_deterministic(b'message', sigencode=util.sigencode_der)
print(f"DER签名长度: {len(der_sig)}")

总结

你既没理解错Wiki内容,也不是用错了库——只是两者讨论的是ECDSA签名的不同表现形式:一个是原始的数学形式,一个是比特币网络使用的标准化编码形式。

内容的提问来源于stack exchange,提问作者zrbecker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:30:32