You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Python中基于P256曲线的ECDSA实现及公钥重构验签方法咨询

Python中基于P256曲线的ECDSA实现及公钥重构验签方法咨询

嗨,你的这个实现思路完全没问题!在Python里不管用ecdsa还是PyCryptodome这两个库,都能轻松搞定「从曲线上的点W重构公钥+验签」的流程,我给你分别写个P256曲线下的可运行示例,你一看就懂:

一、用ecdsa库实现

这个库的API更贴近ECDSA底层逻辑,上手特别直观:

1. 签名端(生成密钥、签名、提取公钥点W)

先模拟签名侧的操作,生成密钥对、签名数据,再把公钥的x/y坐标(也就是你说的W点)、原始数据、签名一起传输:

import ecdsa
import hashlib

# 生成P256曲线(对应NIST256p标准)的密钥对
sk = ecdsa.SigningKey.generate(curve=ecdsa.NIST256p)
vk = sk.get_verifying_key()

# 待签名的原始数据
data = b"这是要被签名的业务数据内容"

# 用SHA-256哈希后签名(P256曲线标准搭配SHA-256哈希算法)
signature = sk.sign(data, hashfunc=hashlib.sha256)

# 提取公钥的W点坐标(x和y都是整数格式)
pub_key_x = vk.pubkey.point.x()
pub_key_y = vk.pubkey.point.y()

# 这里可以把x/y转成十六进制字符串或固定长度字节流,和data、signature一起传输

2. 验签端(重构公钥+验证签名)

到了验签侧,拿到传输过来的参数后,就可以重构公钥并验签了:

import ecdsa
import hashlib

# 假设从传输通道解析得到的参数(实际场景替换成你接收的真实数据)
received_data = b"这是要被签名的业务数据内容"
received_signature = b"..."  # 签名端传来的签名字节流
received_x = 123456...  # 签名端传来的公钥x坐标整数
received_y = 789012...  # 签名端传来的公钥y坐标整数

# 从x/y坐标重构P256曲线的公钥
curve = ecdsa.NIST256p
pub_key_point = curve.curve.point(received_x, received_y)
reconstructed_vk = ecdsa.VerifyingKey.from_public_point(pub_key_point, curve=curve)

# 执行签名验证
try:
    reconstructed_vk.verify(received_signature, received_data, hashfunc=hashlib.sha256)
    print("签名验证通过!")
except ecdsa.BadSignatureError:
    print("签名验证失败!")

二、用PyCryptodome库实现

这个库的封装更偏向通用密码学操作,代码风格也很规整:

1. 签名端(生成密钥、签名、提取公钥点W)

from Crypto.PublicKey import ECC
from Crypto.Signature import DSS
from Crypto.Hash import SHA256

# 生成P256曲线的密钥对
sk = ECC.generate(curve='P-256')
vk = sk.public_key()

# 待签名的原始数据
data = b"这是要被签名的业务数据内容"

# 用SHA-256哈希后签名
hash_obj = SHA256.new(data)
signer = DSS.new(sk, 'fips-186-3')
signature = signer.sign(hash_obj)

# 提取公钥的W点坐标(整数格式)
pub_key_x = vk.pointQ.x
pub_key_y = vk.pointQ.y

# 同样可以把x/y转成易传输的格式,和data、signature一起发送

2. 验签端(重构公钥+验证签名)

from Crypto.PublicKey import ECC
from Crypto.Signature import DSS
from Crypto.Hash import SHA256

# 假设从传输通道解析得到的参数
received_data = b"这是要被签名的业务数据内容"
received_signature = b"..."  # 签名端传来的签名字节流
received_x = 123456...  # 签名端传来的公钥x坐标整数
received_y = 789012...  # 签名端传来的公钥y坐标整数

# 从x/y坐标重构P256曲线的公钥
reconstructed_vk = ECC.construct(
    curve='P-256',
    point_x=received_x,
    point_y=received_y
)

# 执行签名验证
hash_obj = SHA256.new(received_data)
verifier = DSS.new(reconstructed_vk, 'fips-186-3')
try:
    verifier.verify(hash_obj, received_signature)
    print("签名验证通过!")
except ValueError:
    print("签名验证失败!")

最后给你几个实用小提示:

  • 传输公钥坐标时,建议转成32字节的大端字节流(P256的x/y都是32字节长度)或十六进制字符串,这样跨端解析不容易出错
  • 不管用哪个库,验签时的哈希算法必须和签名端完全一致(P256配SHA-256是标准组合)
  • 如果你的W点是压缩格式的公钥(比如仅含x坐标+一个奇偶位),也可以直接用库的解析方法,比如ecdsa.VerifyingKey.from_string(压缩公钥字节, curve=ecdsa.NIST256p),或者PyCryptodome的ECC.import_key(压缩公钥字节)

火山引擎 最新活动