由亚洲DACA区块链协会牵头,清华大学iCenter区块链技术公开课一期学员以及亦来云技术开发团队,于今日在清华大学iCenter召开了关于“防重放攻击”的研讨会议,通过此会议我们进一步提出了关于“防重放攻击”的具体实施方案及建议,供社区同仁参考并指证,希望大家一起推进区块链行业的共同发展。
防重放攻击研讨会现场
具体方案如下:
一、什么是重放攻击
重放攻击是说在比特币硬分叉后,两个链上都有继承自原链的utxo(未花费交易),我们假定分叉后的链一个叫做原链,一个叫做新链,如果在原链上发生一笔由Alice到Bob的转账,交易中的vin(输入交易)用的是继承自分叉前的utxo,那么这笔交易如果被发送到新链上面,新链的节点会验证通过这笔交易,交易也会被挖到区块的节点打包到区块中,并且被其他节点验证通过,造成的结果就是Alice在两条链上的代币资产都会减少。此过程反过来从新链到原链发起攻击也成立。
二、DACA的防重放攻击方案
之所以重放会成功,是因为重放交易满足了以下两个必要条件:
1. 被花费的utxo都继承自分叉前,并且在两条链上都还没有被花费。
2. 两条链的交易签名验证方式相同
对于第一个条件,可以通过分叉后将自己的所有比特币资产(也就是所有utxo)全部转移到自己新的比特币地址的方式来避免被攻击,当然这会损失一定的手续费,而且需要用户自己操作。
我们的防重放方案是想办法让第二个条件不成立,就是说修改交易的签名和验证逻辑,让分叉后的两个链的的交易签名互相不认,来达到防重放的目的。
代码修改说明:
1、修改unit256.h,为class base_blob增加negate方法,此方法用于将base_blob类型实例中存储的内容按bit取反,比如01001取反后变为10110
2、修改script/sign.cpp,在TransactionSignatureCreator::CreateSig方法中调用hash.negate(),这个修改是在签名的时候将待签名交易内容的哈希值按位取反。
3、修改script/interpreter.cpp,在TransactionSignatureChecker::CheckSig方法中调用sighash.negate(),这个修改是在验证签名前,将待验证交易内容的哈希值按位取反。
经过以上修改,在新链上验证的签名多了一道取反操作,原链上的签名在新链上会验证不通过,同样,新链上的交易在原链上也会验证不通过。
修改的代码经过在比特币regtest网络上的测试,证明原链和新链节点间不能验证通过对方的交易,新链节点间交易可以验证通过。
三、补充说明
对此方案的影响做以下几点说明:
1、只影响对交易的验证,不影响基于pow的共识过程。
2、只需要修改新链程序,不需要修改原链程序。
另外,同样基于修改签名的思路,我们还有两个备选方案:
1、对交易内容做2次哈希运算,双哈希的好处是:完全采用比特币内置的算法,容易实现,安全风险低,而且可以减慢暴力破解时尝试一个值的时间,也从侧面增加了安全性。
2、更换哈希算法,将sha256(属于sha-2家族)更换为sha3算法,此算法具有更高的安全性,以太坊使用了此算法。
DACA协会
2017年7月