昨天啃了ecdsa用私钥签名摘要,对这部分多了一些了解(其中我并不清楚签名过程中到底做了什么,这部分更加深奥,不去啃了),今天继续学习如何用公钥验证。
(图源 :pixabay)
简单的示例
首先最简单的签名与验证代码如下:
from ecdsa import SigningKey
sk = SigningKey.generate(curve=ecdsa.SECP256k1)
vk = sk.verifying_key
signature = sk.sign(b"message")
print(vk.verify(signature, b"message"))
在上述代码中,我们用SigningKey
对message这个消息签名,然后用verifying_key
对签名进行校验。
但是我们的例子略微复杂,所以我们先来回顾一下我们如何签名的。
回顾签名
在我们之前的代码中,是针对消息摘要进行的签名,并且SigningKey是使用我们之前文章中生成的私钥。
message = "Hello world!"
digest = hashlib.sha256(bytes(message, 'utf-8')).digest()
private_key = "415ac848c316b406920e0a4b43adc7f93c45bb89124f80ced8d1f50fae4f080d"
sk = ecdsa.SigningKey.from_string(unhexlify(private_key), curve=ecdsa.SECP256k1)
并且根据回调函数(sigencode
)的不同,ecdsa.util.sigencode_der
或者ecdsa.util.sigencode_string
分别得出sigder
以及sigstr
两种格式的签名:
k = 1
sigder = sk.sign_digest(digest,sigencode=ecdsa.util.sigencode_der, k=k)
sigstr = sk.sign_digest(digest,sigencode=ecdsa.util.sigencode_string, k=k)
签名验证
因为公钥本来就是从私钥生成的,所以我们可以直接从SigningKey
来获得VerifyingKey
:
vk = sk.get_verifying_key()
然后我们就可以使用VerifyingKey
来验证签名了:
print(vk.verify_digest(sigstr, digest, sigdecode=ecdsa.util.sigdecode_string)) # True
print(vk.verify_digest(sigder, digest, sigdecode=ecdsa.util.sigdecode_der)) # True
需要注意的是生成签名时的回调函数为sigencode_xxx
,而校验签名时的回调函数为:sigdecode_xxx
,encode和decode不细看区别不出来,不过代码里写错了可就妥妥地要出错了。
如果我们看一下代码,就不难发现,无论是der还是str格式的签名,都要先恢复成r,s
的,这就是decode回调的意义所所在了:
再谈公钥
我们的结论是公钥是从私钥生成的,比如上述代码:
vk = sk.get_verifying_key()
我们可以将vk打印出来:
不能发现,其实和我们之前用私钥生成的公钥完全一样的(非压缩,不带前缀):
f5810b31e23d76a1b8a76cfe43d7168abbaf6363c3927aafaf4751697488d329147d6d4e232cf7de60d94b3962ea260894fe02274223b2a3050eb9b7e655ab4e
其实我们也可以直接用公钥生成VerifyingKey
:
public_key = "f5810b31e23d76a1b8a76cfe43d7168abbaf6363c3927aafaf4751697488d329147d6d4e232cf7de60d94b3962ea260894fe02274223b2a3050eb9b7e655ab4e"
vk = ecdsa.VerifyingKey.from_string(unhexlify(public_key), curve=ecdsa.SECP256k1)
print(hexlify(vk.to_string()).decode())
这个输出的vk和之前的是一样的,其实这才是vk的打开正确方式,因为校验的时候,我们往往都是只有公钥没有私钥的。
相关链接
- https://github.com/ecdsa/python-ecdsa
- https://github.com/warner/python-ecdsa
- https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki#der-encoding
- 每天进步一点点:学习用私钥签名
- 每天进步一点点:STEEM/HIVE私钥/公钥的还原
- 每天进步一点点:STEEM/HIVE公钥(Public Key)生成探索
- 每天进步一点点:STEEM/HIVE私钥(Private Key)生成探索
This page is synchronized from the post: ‘每天进步一点点:学习用公钥验证’