ECC256签名
ECC256签名
-
ECC256是一种非对称加密算法,ECC256签名是先对明文消息进行SHA256生成1个32字节即256bit的消息摘要,
再对其进行ECC256加密,生成签名。通常使用私钥加密生成签名,公钥解密验签。 -
ECC256其私钥长度为256bit,而公钥长度为512bit。公钥一般表示为一个 压缩格式 或 未压缩格式。
- ECC 公钥是由一个点表示的,点坐标是 2 个 256 位的整数(
x
和y
坐标),所以公钥的长度是 2 × 256 位 = 512 位,也就是 64 字节。
- ECC256签名值
(r, s)
长度为64个字节。
- r(32字节): 椭圆曲线上的随机点的 x 坐标(经过模运算)。
- s(32字节): 结合私钥计算出的 签名校验值,用于验证签名的合法性。
- r 和 s 的存储格式:
-
ASN.1 DER 格式(通常 70-72 字节,不定长)
-
Raw 二进制格式(固定 64 字节 r || s,分别占 32 字节)
-
备注: 当解析 ASN.1 DER 编码的签名时,
s
可能会出现 33 个字节 而不是 32 字节,通常是由于前导 0x00(leading zero)的存在。这是因为 ASN.1 的 INTEGER 类型 需要保证它是无符号整数,避免被误认为负数。
- 使用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
- 利用(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")
- 参考文档及工具