Skip to content

可编辑区块链,使用基于RSA假设及因数分解的陷门哈希函数替换以太坊geth客户端的keccak256算法并开放出JSON-RPC接口,实现单节点修改指定区块数据、多节点同步修改区块数据的功能。

License

Notifications You must be signed in to change notification settings

crypto-hacker/redactable-blockchain

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

redactable-blockchain

基于以太坊geth客户端的可编辑区块链,使用基于RSA假设及因数分解的变色龙哈希函数替换了以太坊keccak256哈希算法,实现了单节点中修改指定区块数据、多节点同步修改的逻辑。

修改步骤:

1.在ethereum/go-ethereum中新建包super,用于存放geth项目中新增的可编辑代码逻辑。

2.在super包中新建包chameleon,将实现“基于RSA假设和因数分解的变色龙hash函数”算法的代码放入此包中,供geth项目中其他需要更改的部分调用。算法实现的时候使用了标准crypto库中RSA加密算法里面实现的emsa-pss-encode算法,由于它们是非公开的,因此可采用的办法是将相关函数复制到chameleon包中。

Chameleon包公开函数只有两个——Hash和UForge。Hash函数所需的参数为common.Hash类型的msg和byte切片类型的salt,前者为消息经过首次哈希后得到的结果,可以使用的哈希算法没有限制,后者为初始随机数,只需要使用rand函数来生成就行,函数返回值为经过该陷门哈希算法哈希后的结果。UForge函数所需的参数为common.Hash类型的oldMsg、common.Hash类型的newMsg和byte切片类型的oldSalt,oldMsg为原消息的二次哈希值,newMsg为新消息的一次哈希值,oldSalt为原消息的随机数,函数返回值为哈希碰撞后的新随机数,该随机数和newMsg作为参数传入Hash函数中,得到的返回值与oldMsg和oldSalt作为参数传入Hash函数中得到的返回值相同,这样就实现了带陷门可更改的哈希函数。

3.修改types包中Header结构体,增加byte切片类型的ChameleonSalt字段和bool类型的IsModified字段,修改Hash函数,函数内增加一个chameleonHeader结构体,该结构体除了增加一个IsModified字段外,其余字段与原Header结构体相同,调用chameleon包中的Hash,修改Header结构体Hash函数的返回值为chameleonHeader的陷门哈希值。

4.core包中的Genesis结构体增加byte切片类型的ChameleonSalt字段和bool类型的IsModified字段,ToBlock方法中的head参数在实例化的时候增加ChameleonSalt和IsModified字段,DefaultGenesisBlock函数中增加ChameleonSalt和IsModified的值。除此之外,MarshalJSON方法和UnmarshalJSON里面的Genesis结构体增加相应的字段并在实例化的时候赋上相应的值。这个包的作用是生成创世区块,创世区块的内容决定了区块链是否能成功运行,因此必须修改以兼容可编辑区块链的功能。

5.修改types包中的rlpHash函数,将其从包私有修改为包公开。该函数的作用是将任意结构类型的对象经过rlp序列化后计算hash值,对区块进行陷门哈希的时候需要用到它。

6.在types包中的Block结构体中增加SetHeader方法,函数参数为*Header,用于修改Block的区块头。

7.在core包中的BlockChain结构体中增加Modify方法,参数为int类型的num,为需要修改的区块的区块号。该方法中有一个chameleonHeader结构体,该结构体除了增加一个IsModified字段外,其余字段与原Header结构体相同。实例化chameleonHeader的时候,首先通过num取得对应的区块链,然后将其除ChameleonSalt以外的字段全部赋值到chameleonHeader实例化对象中。

赋值完之后,调用types包中的RlpHash函数获得oldMsg,参数为chameleonHeader的实例化对象,更改相应的数据,并且把IsModified的值从false改为true,再次调用RlpHash函数获得newMsg,然后调用chameleon包中的UForge函数计算哈希碰撞,得到的新ChameleonSalt并赋值给chameleonHeader实例化对象,调用num指定的block的SetHeader方法,将其区块头换为chameleonHeader。

此时内存中的区块链已经修改完毕,接下来是数据持久化。Geth的数据持久化使用的是Google的key-value型数据库leveldb,在rawdb中已经封装好。首先调用rawdb包的ReadCanonoicalHash函数获得num指定的区块在外存中存储时的hash索引,然后调用DeleteBlock删除指定区块,最后调用WriteBlock修改过的区块写入。

8.修改clique包中的Clique结构体的Seal方法,为header的ChameleonSalt字段设置256位的随机值。

9.修改clique包中Snapshot结构体的apply方法,在验证区块的代码增加if条件句,代码逻辑为如果header的IsModified为true(区块被更改过),则跳过验证。

10.ethapi包中的RPCMarshalHeader函数增加chameleonSalt和isModified键值对,该函数的作用是其它客户端通过JSONRPC调用获取区块数据的函数时将区块数据解析。由于可编辑区块链增加了ChameleonSalt和IsModified两个字段,因此其它客户端要想得到它们,必须在这里增加相应的解析。到此为止单节点上的区块链已经修改成功,接下来需要多节点之间的交互,以让区块链网络中的所有节点都同步修改。

11.node包中的Node结构体增加AddAPI方法,参数分别为string类型的namespace和interface{}类型的api,该函数的作用是开放JSONRPC的注册,namespace参数是JSONRPC中指定的调用前缀,api是通过JSONRPC调用的功能函数。

12.node包中的Node结构体增加Services方法,用于获取Node结构体的私有services字段。该字段是一个键为reflect.Type类型、值为Service类型的map,可以通过它来获取已经注册的服务。

13.eth包protocol.go文件中增加消息码常量SuperMsg=0x08,该消息码用于识别新增的业务逻辑。ProtocolManager结构体的handleMsg方法中switch中新增case条件,当消息码的值等于SuperMsg的时候,解析msg为num,调用blockchain实例化对象的Modify方法,修改num指定的区块。

14.eth包中的peer结构体增加SendInfo方法,参数为string类型的num,调用p2p包中的Send方法,将num广播到其他节点处,其中消息码为常量SuperMsg。

15.eth包中的ProtocolManager结构体新增BrodcastInfo方法,参数为string类型的num,代码逻辑为首先获取ProtocoalManager存储的所有节点句柄,然后调用节点句柄的SendInfo方法,将num作为参数传入。

16.eth包中的Ethereum结构体增加PretocolManager方法,返回该结构体的非公开字段protocolManager。

17.super包中增加SuperAPI结构体,包含类型为*eth.Ethereum的e,包含ModifyBlock方法,参数为string类型的num,指定需修改的区块,要求传值的时候必须使用string类型的十六进制。该方法首先通过e字段获取blockchain,调用其Modify方法,更改num指定的区块,然后调用e字段的ProtocolManager方法,获得*eth.Ethereum的私有字段protocolManager,调用其BroadcastInfo方法,广播num到其它节点处。

18.main包中增加prepareSuper函数,参数为*node.Node类型node和*eth.Ethereum类型的ethereum,该函数中调用了node的AddAPI方法注册JSONRPC的服务,命名空间为“super”,注册的服务为super包中新增的代码逻辑。

19.修改main包中的geth函数、localConsole函数,调用node的Services函数获取已经注册的所有服务,存储它们的数据结构为map,通过反射获取eth.Ethereum{}的指针类型,作为键获取相应的服务,然后调用prepareSuper函数,注册super包的新增服务。

修改完成后,可以以正常方式启动修改过后的客户端。当区块链网络运行的时候,可以向某个节点监听的端口发送method为“super_modifyBlock”的JSON-RPC便可以修改指定区块,该节点修改成功后,会广播给其他节点,让它们同步修改区块数据。

区块数据的可变性在于陷门哈希函数,原区块数据作为oldMsg,修改过后的区块数据作为newMsg,oldMsg和chameleonSalt经过陷门哈希函数计算后得到的哈希值与newMsg和哈希碰撞后得到的新chameleonSalt经过陷门哈希函数计算得到的哈希值相同,这就代表区块数据修改前后,该区块的哈希值未改变,因此实现了可编辑区块链。

TODO:

变色龙哈希函数的陷门参数是直接写死在代码中,实际应用中应该由多个监管者掌握陷门。下一步的任务是使用密码学秘密分享算法分割陷门,并设计修改区块数据的权限模块。

About

可编辑区块链,使用基于RSA假设及因数分解的陷门哈希函数替换以太坊geth客户端的keccak256算法并开放出JSON-RPC接口,实现单节点修改指定区块数据、多节点同步修改区块数据的功能。

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published