本发明涉及网络安全技术领域,具体涉及一种基于merkle树的区块链数据修改方法。
背景技术:
随着计算机技术和互联网的不断发展,数据安全越来越重要。区块链是一种分布式去中心化、不可篡改、高安全性的数据存储技术,越来越多的区块链项目开始落地,将数据存储到区块链中确实可以保障数据的完整性和安全性,但正是由于区块链具有不可篡改性,存入区块中的一些错误数据和虚假数据也无法更正和删除。
目前区块链一个重要的应用场景是产品溯源,溯源数据由各个数据提供部门节点上传至区块链中,这一般是人工手动录入的过程,就难免会发生数据输入错误的情况,尽管有其他节点确认机制,但也不能保证数据百分百正确。不管是上的类似以太坊这样的公链还是搭建的私链,数据一旦写入区块中都是不可更改的,这样用户查询到产品溯源信息很可能就有一部分是错误的,而产品溯源本身就要求真实性,所以对区块链数据修改方案的研究是有必要的。
文献1:任艳丽,徐丹婷,张新鹏,谷大武.可修改的区块链方案[j/ol].软件学报:1-14[2020-04-27],公开了一种基于陷门单向函数和新型区块链结构的区块链数据修改方案,通过引入机动因子重构区块签名子块,超过一定阈值的节点同意后便可实现区块数据的合法修改。该方案虽然在不修改区块链完整性验证方式的前提下实现了区块中数据的修改,但是只对采用空间证明(pospace)共识机制的这种具有特殊区块结构的区块链有效,采用工作量证明(pow)、权益证明(pos)以及委托权益证明(dpos)等其他共识机制的区块链则无法通过该方案实现数据修改。
技术实现要素:
本发明的目的是:为了解决上述问题,本发明提出一种基于merkle树的区块链数据修改方法。该方法通过加入扩展区的方式实现对区块链数据的修改。将区块划分为数据区和扩展区,两个区分开构建merkle树,打包区块时只将数据写入数据区,若要修改某个错误数据,获得一定数量节点的同意后在该数据所在区块的扩展区里重写该数据即可。
为了解决上述问题,本发明所采用的技术方案是:
一种基于merkle树的区块链数据修改方法,其特征在于,包括:
步骤1,将区块链的区块体划分为数据区和扩展区,数据只存入数据区,两个区单独构建merkle树,将两棵merkle树的根分别存入区块头中;
步骤2,对于需要修改的错误数据,获得一定数量节点同意后,在扩展区中重写该数据并重新构建扩展区的merkle树。
进一步的,所述步骤1具体包括如下步骤:
步骤1.1,将区块体划分为数据区和扩展区,打包区块时,将所有数据分别计算哈希值作为叶子节点,叶子节点两两配对后再计算哈希值作为父节点,相邻的两个父节点再两两配对计算哈希值,以此类推,直到只剩一个节点,为根节点,以此来构建merkle树1,将merkle树1存入数据区;
步骤1.2,扩展区存放只含有根节点的merkle树2,该根节点的值和数据区根节点的值相同;
步骤1.3,将两个根节点值merkle1_root和merkle2_root存入区块头中,并将前一个区块数据区进行哈希计算得到的哈希值prehash存入区块头中,区块之间通过prehash形成前后链接关系,由于数据修改只改变扩展区,数据区不变,所以在数据修改后,前后区块间的链接关系不会被破坏。
进一步的,所述步骤2具体包括如下步骤:
步骤2.1:某个节点如果发现自己上传的数据有误,需要发起区块数据修改请求,将该数据所在的区块号、错误数据id和正确数据一起签名之后向全网节点广播;
步骤2.2,其他节点收到消息后对签名和数据进行验证,验证通过后决定是否同意此次数据修改;
步骤2.3,当获得一定数量节点的同意后即可对区块数据进行合法修改。
进一步的,当扩展区的merkle根和数据区的merkle根相同时,说明该区块未进行过数据修改,数据区中的数据保持不变,将要修改的数据在扩展区中重写为修改后的数据,数据id和数据区中原始数据id保持一致,然后进行哈希计算得到该数据的哈希值,作为叶子节点并与自身配对构建merkle树。
进一步的,当扩展区的merkle根和数据区的merkle根不同时,说明已经进行过数据修改,若扩展区中最后两个数据的id相同,说明是和自身配对的,取其中一个与新的修改数据哈希值重新配对,并重新构建merkle树;若扩展区中最后两个数据id不同,新的修改数据哈希值仍然和自身配对,再重新构建merkle树;修改成功后将区块头中的merkle2_root更新为扩展区中新的merkle根。
进一步的,对于完成数据修改后的区块,其区块头中的merkle2_root会发生改变;由于区块初始状态下,merkle1_root和merkle2_root是相同的,那么在向区块中获取数据时,只需要先比对区块头中merkle1_root和merkle2_root的值是否相同,若相同,直接将数据区的数据全部取出;若不相同,说明区块数据已经修改,先将扩展区中的数据全部取出,并单独取出所有的数据id集合,数据区中数据id在该集合中的数据均为已修改数据的原始数据,需要剔除,剔除之后的数据区数据和加上扩展区中的数据为区块中的有效数据。
进一步的,首先在可信节点处重新构建数据区的merkle树和扩展区中的merkle树,得到可信的merkle1_root集合和merkle2_root集合;然后对其他节点进行验证,验证时需要用可信merkle1_root集合和可信merkle2_root集合分别与所有区块头中merkle1_root和merkle2_root逐一比对,如果都一致,则该条链是完整的,不管是merkle1_root还是merkle2_root,只要出现不一致的情况,即为区块数据不完整,舍弃该区块,从已验证节点处重新同步数据。
进一步的,如果发现非法数据修改行为,直接将所在区块的扩展区和区块头中的merkle2_root重置为初始状态,取数据时仍然会从数据区取出原数据,数据不会丢失或被破坏。
本发明提供的上述技术方案的有益效果至少包括:本发明相对于现有技术的优点是:本发明针对写入区块链中的错误数据无法修改或删除的问题,通过加入扩展区的方式实现对区块链数据的修改。将区块划分为数据区和扩展区,两个区分开构建merkle树,打包区块时只将数据写入数据区,若要修改某个错误数据,获得一定数量节点的同意后在该数据所在区块的扩展区里重写该数据即可。并从数据修改和完整性验证两方面进行了实验验证,实验结果表明该方案具有较高的可行性。
本发明的其它特征和优点将在随后的说明书中阐述,并且,部分地从说明书中变得显而易见,或者通过实施本发明而了解。本发明的目的和其他优点可通过在所写的说明书、权利要求书、以及附图中所特别指出的结构来实现和获得。
下面通过附图和实施例,对本发明的技术方案做进一步的详细描述。
附图说明
附图用来提供对本发明的进一步理解,并且构成说明书的一部分,与本发明的实施例一起用于解释本发明,并不构成对本发明的限制。在附图中:
图1是本发明实施例公开的可修改数据的区块结构。
图2是本发明实施例公开的修改数据后的区块结构。
图3是本发明实施例公开的数据修改前的区块2数据。
图4是本发明实施例公开的数据修改后的区块2数据。
具体实施方式
下面将参照附图更详细地描述本公开的示例性实施方式。虽然附图中显示了本公开的示例性实施方式,然而应当理解,可以以各种形式实现本公开而不应被这里阐述的实施方式所限制。相反,提供这些实施方式是为了能够更透彻地理解本公开,并且能够将本公开的范围完整的传达给本领域的技术人员。
本发明将区块链的区块体划分为数据区和扩展区,提出一种基于merkle树的区块链数据修改方案。数据只存入数据区,两个区单独构建merkle树,将两棵merkle树的根分别存入区块头中。对于需要修改的错误数据,获得一定数量节点同意后,在扩展区中重写该数据并重新构建扩展区的merkle树即可。下面结合实例对本发明进行说明。
1区块结构划分
传统不可修改的区块链,区块由区块头和区块体两部分组成,区块体中的merkle树是由该区块中所有数据计算哈希值后两两配对辗转计算哈希值构成的,区块头中存有merkle根的值。如果区块中的某个数据被修改了,那么它的哈希值就会发生改变,该叶子节点的改变会影响整棵merkle树,最终区块头中的merkle根也会发生改变。区块链进行完整性验证的时候会从可信节点处重新构建merkle树,得到可信merkle根,修改数据的区块的merkle根必然与可信merkle根不相同,也就无法通过完整性验证,所以对于传统区块链来说,一旦区块生成,数据是无法修改的。
本方案将区块体划分为数据区和扩展区,打包区块时,将数据和构建好的merkle树按照传统区块链的方式存入数据区,扩展区存放只含有根节点的merkle树,该根节点的值和数据区的merkle根相同,将两个merkle根都放入区块头中,区块头中prehash为前一个区块数据区的哈希值,因为数据修改只有数据区是不发生变化的,只存数据区的哈希值,在数据修改后也不会破坏前后区块间的链接关系。可修改数据的区块结构如图1所示。
2数据修改方法
某个节点如果发现自己上传的数据有误,需要发起区块数据修改请求,将该数据所在的区块号、错误数据id和正确数据一起签名之后向全网节点广播,其他节点收到消息后对签名和数据进行验证,验证通过后决定是否同意此次数据修改,当获得一定数量节点的同意后即可对区块数据进行合法修改。
当扩展区的merkle根和数据区的merkle根相同时,说明该区块未进行过数据修改,数据区中的数据保持不变,将要修改的数据在扩展区中重写为修改后的数据,数据id和数据区中原始数据id保持一致,然后进行哈希计算得到该数据的哈希值,作为叶子节点并与自身配对构建merkle树。
当扩展区的merkle根和数据区的merkle根不同时,说明已经进行过数据修改,若扩展区中最后两个数据的id相同,说明是和自身配对的,取其中一个与新的修改数据哈希值重新配对,并重新构建merkle树;若扩展区中最后两个数据id不同,新的修改数据哈希值仍然和自身配对,再重新构建merkle树。修改成功后将区块头中的merkle2_root更新为扩展区中新的merkle根,修改后的区块如图2所示。
从图1和图2的对比中可以看出,数据修改前后,数据区和merkle1_root都是不发生改变的,修改的只是扩展区和merkle2_root。这样设计的目的在于:
(1)数据区的数据一般比较多,merkle树的结构较为复杂,若直接在数据区中修改数据,会引发整棵merkle树的重新构建,数据修改以及修改后节点间的数据同步会花费较长的时间。扩展区的数据量较少,merkle树的层数也较少,重新构建会比较快,这样数据修改带来的时间开销就会比较小。
(2)对区块链的攻击有多种攻击手段,攻击者如果使用某种攻击手段通过了数据修改合法性验证,完成了区块中数据的非法修改。在发现该非法行为后,直接将扩展区中的数据销毁,merkle树和区块头中的merkle2_root重置为初始状态即可,原数据仍然存储在数据区中,不会对区块链上的原始数据产生影响。
3修改后的数据获取
对于完成数据修改后的区块,其区块头中的merkle2_root会发生改变。由于区块初始状态下,merkle1_root和merkle2_root是相同的,那么在向区块中获取数据时,只需要先比对区块头中merkle1_root和merkle2_root的值是否相同,若相同,直接将数据区的数据全部取出;若不相同,说明区块数据已经修改,先将扩展区中的数据全部取出,并单独取出所有的数据id集合,数据区中数据id在该集合中的数据均为已修改数据的原始数据,只需要取出除这些原始数据外的其他数据即可。
4完整性验证
传统结构的区块链完整性验证是从可信节点处获取数据,重新构建所有区块中的merkle树,得到可信merkle_root集合,再用该可信merkle根集合和其他节点所有区块头中的merkle根比对,从而验证其完整性。对于前面所提出的新型结构区块链,完整性验证与传统结构区块链略有不同。首先在可信节点处重新构建数据区的merkle树和扩展区中的merkle树,得到可信的merkle1_root集合和merkle2_root集合。然后对其他节点进行验证,验证时需要用可信merkle1_root集合和可信merkle2_root集合分别与所有区块头中merkle1_root和merkle2_root逐一比对,如果都一致,则该条链是完整的,不管是merkle1_root还是merkle2_root,只要出现不一致的情况,即为区块数据不完整,舍弃该区块,从已验证节点处重新同步数据。
可修改型区块链比传统结构区块链多了重新构建merkle2树和merkle2_root的比对工作。由于只有进行过数据修改的区块才需要重新构建merkle2树,而需要修改数据的区块占比很小,构建merkle2树所需时间较短,merkle2_root的比对也只是简单字符串匹配,所需时间也较短。所以可修改型区块链的完整性验证的时间花销只比传统结构区块链稍大一点,对验证效率的影响几乎可以忽略,后面会对传统结构区块链和本节所提出的数据可修改型区块链进行完整性验证时间花销的对比实验。
5实验与结果分析
5.1实验环境
使用python3语言和pythonflaskweb框架编写实现了一个传统区块结构的区块链原型和一个采用2.1节中设计的数据可修改型区块结构的区块链原型,以6台配置不同的计算机作为区块链节点,6个节点的配置信息如下表1所示,分别使用这两个区块链原型搭建了数据不可修改型测试区块链1和数据可修改型测试区块链2,从区块链中区块数据的修改和修改数据后完整性验证的时间花销进行实验,使用postman作为web接口请求工具来获取数据。
表1节点配置信息
5.2区块数据修改
使用测试区块链2进行实验,将数据修改合法性验证的节点数量设置为4个。上传报告编号为yw2008-006的检验报告,为了模拟录入数据时的输入错误,将报告编号错误地输入为yw2008-0006。由于区块链初始化会生成一个创世区块,所以检验报告打包存放在区块2中,编写区块数据获取接口/chain,使用postman请求/chain接口,返回的区块2的数据如图3所示。
使用节点1向其他节点发起数据修改请求广播,操作节点2、节点3、节点4和节点5同意数据修改,模拟数据修改的合法性验证。4个节点均返回确认信息后,节点1对区块2进行错误数据的修改,将报告编号更正为yw2008-006,使用postman再次请求/chain接口,返回的区块2数据如图4所示。
从图3和图4中可以看出,数据修改前后只有merkle2_root的值发生了改变,merkle1_root的值未发生改变,说明了数据修改只改变了扩展区中的merkle2树,未改变数据区中的merkle1树,符合第2节的修改方案设计。由于区块头中prehash为前一个区块数据区的哈希值,而数据修改又不会改变数据区,所以数据修改后当前数据区的哈希值和下一个区块头中的prehash仍然是一致的,说明区块数据修改不会破坏前后区块间的链接关系。
5.3完整性验证时间花销
将300个产品检验报告数据10个一组分为30组,循环上传到测试区块链1中。创世区块随区块链系统的首次运行而创建,无法存储数据,从区块2开始每个区块存储一组10个产品检验报告数据。当产生3001个区块时,对节点6进行区块链完整性验证,将节点1到节点5分别作为可信节点进行5次完整性验证,记录每次验证所花费的时间。然后将6个节点的测试区块链1系统都停止运行,启动测试区块链2,以相同的方式循环上传30组产品检验报告,并通过数据修改申请分别修改区块2到区块3001这3000个区块数据区中id为1的数据,完成数据修改后,再以节点1到节点5为可信节点对节点6进行5次完整性验证,并记录每次验证所花费时间。两个测试区块链的完整性验证时间花销如下表2所示。
表2完整性验证时间花销
从表2中可以看出,测试区块链2以6个节点作为可信节点的完整性验证时间花销与测试区块链1相比,均出现了毫秒级的轻微增长。在区块链实际运行过程中,毫秒级的时间花销增长如果不使用计时算法是无法察觉到的,并且这是在3000个区块均因数据修改而重新构建扩展区merkle树的极端情况下。实际使用场景基本不会出现如此多的区块数据修改,那么完整性验证时间花销的增长将会更加不明显。由此可以说明扩展区的加入不会引起完整性验证时间花销的明显变化,对验证效率的影响可以忽略。
5.4安全性分析
数据可修型区块链与传统结构区块链的区别在扩展区和扩展区merkle树的加入,由于传统结构区块链已具有不可篡改性,所以其安全性依赖于扩展区的安全性。在可修改型区块链中,需要获得一定数量节点的合法性确认才能对区块数据进行修改,确认节点数的设置与全网节点数相关,越多越安全,但也会带来更长的确认等待时间,在实际系统运行过程中根据实际需要来设置节点数。当确认节点数足够多时,若要获得所有节点的合法性确认,其实现难度不亚于区块链中“51%攻击”的难度。即使确认节点数设置的不够多,攻击者使用某种未知的攻击手段通过了数据修改合法性验证,进行了区块数据的篡改,一旦发现该行为,直接将扩展区数据清空,扩展区中的merkle2树和区块头中的merkle2_root重置为初始状态即可,篡改前的原数据仍然存储在数据区中,不会对区块链的原始数据产生影响。
结语:本发明针对写入区块链中的错误数据无法修改或删除的问题,将区块划分为数据区和扩展区,数据区存储写入区块中的数据,扩展区用于修改时的数据重写,两个区单独构建merkle树,区块头中存有两个区的merkle根,以此提出一种区块链数据修改方案。并搭建实验环境从数据修改和完整性验证两方面进行了实验,实验结果表明该方案具有较高的可行性。
应该明白,公开的过程中的步骤的特定顺序或层次是示例性方法的实例。基于设计偏好,应该理解,过程中的步骤的特定顺序或层次可以在不脱离本公开的保护范围的情况下得到重新安排。所附的方法权利要求以示例性的顺序给出了各种步骤的要素,并且不是要限于所述的特定顺序或层次。
在上述的详细描述中,各种特征一起组合在单个的实施方案中,以简化本公开。不应该将这种公开方法解释为反映了这样的意图,即,所要求保护的主题的实施方案需要清楚地在每个权利要求中所陈述的特征更多的特征。相反,如所附的权利要求书所反映的那样,本发明处于比所公开的单个实施方案的全部特征少的状态。因此,所附的权利要求书特此清楚地被并入详细描述中,其中每项权利要求独自作为本发明单独的优选实施方案。
本领域技术人员还应当理解,结合本文的实施例描述的各种说明性的逻辑框、模块、电路和算法步骤均可以实现成电子硬件、计算机软件或其组合。为了清楚地说明硬件和软件之间的可交换性,上面对各种说明性的部件、框、模块、电路和步骤均围绕其功能进行了一般地描述。至于这种功能是实现成硬件还是实现成软件,取决于特定的应用和对整个系统所施加的设计约束条件。熟练的技术人员可以针对每个特定应用,以变通的方式实现所描述的功能,但是,这种实现决策不应解释为背离本公开的保护范围。
结合本文的实施例所描述的方法或者算法的步骤可直接体现为硬件、由处理器执行的软件模块或其组合。软件模块可以位于ram存储器、闪存、rom存储器、eprom存储器、eeprom存储器、寄存器、硬盘、移动磁盘、cd-rom或者本领域熟知的任何其它形式的存储介质中。一种示例性的存储介质连接至处理器,从而使处理器能够从该存储介质读取信息,且可向该存储介质写入信息。当然,存储介质也可以是处理器的组成部分。处理器和存储介质可以位于asic中。该asic可以位于用户终端中。当然,处理器和存储介质也可以作为分立组件存在于用户终端中。
对于软件实现,本申请中描述的技术可用执行本申请所述功能的模块(例如,过程、函数等)来实现。这些软件代码可以存储在存储器单元并由处理器执行。存储器单元可以实现在处理器内,也可以实现在处理器外,在后一种情况下,它经由各种手段以通信方式耦合到处理器,这些都是本领域中所公知的。
上文的描述包括一个或多个实施例的举例。当然,为了描述上述实施例而描述部件或方法的所有可能的结合是不可能的,但是本领域普通技术人员应该认识到,各个实施例可以做进一步的组合和排列。因此,本文中描述的实施例旨在涵盖落入所附权利要求书的保护范围内的所有这样的改变、修改和变型。此外,就说明书或权利要求书中使用的术语“包含”,该词的涵盖方式类似于术语“包括”,就如同“包括,”在权利要求中用作衔接词所解释的那样。此外,使用在权利要求书的说明书中的任何一个术语“或者”是要表示“非排它性的或者”。