ECC256签名

ECC256签名

  1. ECC256是一种非对称加密算法,ECC256签名是先对明文消息进行SHA256生成1个32字节即256bit的消息摘要,
    再对其进行ECC256加密,生成签名。通常使用私钥加密生成签名,公钥解密验签。

  2. ECC256其私钥长度为256bit,而公钥长度为512bit。公钥一般表示为一个 压缩格式未压缩格式

  • ECC 公钥是由一个点表示的,点坐标是 2 个 256 位的整数(xy 坐标),所以公钥的长度是 2 × 256 位 = 512 位,也就是 64 字节。
  1. ECC256签名值 (r, s) 长度为64个字节
  • r(32字节): 椭圆曲线上的随机点的 x 坐标(经过模运算)。
  • s(32字节): 结合私钥计算出的 签名校验值,用于验证签名的合法性。
  1. r 和 s 的存储格式:
  • ASN.1 DER 格式(通常 70-72 字节,不定长)

  • Raw 二进制格式(固定 64 字节 r || s,分别占 32 字节)

  • 备注: 当解析 ASN.1 DER 编码的签名时,s 可能会出现 33 个字节 而不是 32 字节,通常是由于前导 0x00(leading zero)的存在。这是因为 ASN.1 的 INTEGER 类型 需要保证它是无符号整数,避免被误认为负数。

  1. 使用OpenSSL进行签名与验签
  • 生成私钥(基于 secp256r1曲线 生成私钥)

    openssl ecparam -genkey -name prime256v1 -noout -out private.pem

  • 查看私钥

    openssl ec -in private.pem -text -noout

  • 生成公钥

    openssl ec -in private.pem -pubout -out public.pem

  • 签名

    openssl dgst -sha256 -sign private.pem -out signature.sig test.bin

    此处生成的signature.sig二进制文件,其格式为ASN.1 DER 格式。

  • 查看签名

    openssl asn1parse -in signature.sig -inform DER

  • 验签

    openssl dgst -sha256 -verify public.pem -signature signature.sig test.bin

  1. 利用(r, s)构造sig文件
# pip install pyasn1

from pyasn1.type.univ import Integer, Sequence
from pyasn1.codec.der.encoder import encode
import binascii
import base64

# 提供的 r 和 s
r_hex = "66bb29edeb1d7d8be7e68a452fa24ebd381372e41709e4a6cdba09438da0baa7"
s_hex = "e6b22c9e625602c0d5109b7944318de921fbbd47481acaf25330c207121a7f6b"

# 转换为字节
r_bytes = binascii.unhexlify(r_hex)
s_bytes = binascii.unhexlify(s_hex)

# 如果 r 或 s 的最高位是 1(>=0x80),需要前面补 0x00
if r_bytes[0] >= 0x80:
    r_bytes = b'\x00' + r_bytes
if s_bytes[0] >= 0x80:
    s_bytes = b'\x00' + s_bytes

# 构造 ASN.1 序列
signature_seq = Sequence()
signature_seq.setComponentByPosition(0, Integer(int.from_bytes(r_bytes, "big")))
signature_seq.setComponentByPosition(1, Integer(int.from_bytes(s_bytes, "big")))

# DER 编码
signature_der = encode(signature_seq)

# 保存为原始 `.sig` 文件
with open("signature.sig", "wb") as f:
    f.write(signature_der)

# 生成 Base64 编码的签名
signature_base64 = base64.b64encode(signature_der).decode("utf-8")

# 保存 Base64 编码的 `.sig` 文件
with open("signature_base64.sig", "w") as f:
    f.write(signature_base64)

print("签名文件已生成:")
print("- 原始二进制格式:signature.sig")
print("- Base64 编码格式:signature_base64.sig")
  1. 参考文档及工具
posted @ 2025-03-04 17:52  决云  阅读(212)  评论(0)    收藏  举报