在之前学习用私钥签名的文章中,虽然我们完成了用私钥进行签名,但是我还留下一下问题,就是生成的签名尽管可以通过验证,但是是否适用于STEEM/HIVE区块链呢?这里涉及到一个知识点就是canonical signature
。
(图源 :pixabay)
canonical signature
说到canonical signature
,就要提到一个Signature Malleability
,简单来讲就是对于同一个HASH,signature (r,s)
以及signature (r, -s (mod N))
都是合法的签名:
In addition for every ECDSA
signature (r,s)
, thesignature (r, -s (mod N))
is a valid signature of the same message.
对于恶意攻击者而言,就可以利用这点来进行重播攻击,将一个交易用不同的签名提交两次(说的是啥?一头雾水ing)。
而杜绝这个问题的一个方法就是对签名的r、s
进行一些约束,只有符合约束的才能算做合法的签名。
steemd中相关代码
在steemd中对应的检查代码如下:
其中两个检查代码分别如下:
如下代码会作为参数传递给签名/验证的相关函数:
has_hardfork( STEEM_HARDFORK_0_20__1944 ) ? fc::ecc::bip_0062 : fc::ecc::fc_canonical );
也就是说HF20之前用fc_canonical
来检查,HF20之后用bip_0062
来检查。话说,这个两个检查哪个更严格一些呢?另外bip_0062中为啥不检查
steem-python 中的相应检查
steem-python中针对用使用SECP256K1
生成的签名使用如下代码检查:
1 | def _is_canonical(self, sig): |
而针对使用ecdsa生成的签名则使用如下代码来检查:
1 | # Make sure signature is canonical! |
可见都不是遵循新的bip_0062
标准。
不过这两组代码现在也都是工作的,我猜测是因为按着bip_0062
标准,上述代码检查后的签名不符合标准的概率微乎其微,所以很难触发吧?😳
相关链接
- https://en.bitcoin.it/wiki/BIP_0062
- Transaction malleability
- https://github.com/steemit/steem-python
- “Canonical” transaction signatures #1944
This page is synchronized from the post: ‘每天进步一点点:”Canonical” 交易签名’