详读论文《Fides: Managing Data on Untrusted Infrastructure 》

微信公众号:Java随笔录
关注可了解更多Java相关的技术分享。问题或建议,欢迎公众号留言!

前段时间看了篇关于外包数据的论文,发表在ICDCS2020上,《Fides: Managing Data on Untrusted Infrastructure》。这篇论文主要解决的问题就是在数据外包的场景中,第三方服务器不可信的情况下怎么进行分布式事务的执行,确保第三方服务器的作恶行为能被数据拥有者检测出来。这边做一下分享。

Background & Intro

在这里插入图片描述

我们来看一下这篇论文的研究背景。其实这已经是个老问题了,举个例子,一个数据拥有者,比如一个初期创业的公司(其实不仅仅局限于初创的公司,大部分体量较大的公司也是一样的),如果他们自己搭建物理服务器,自己进行相应的数据存储服务管理,如此带来的人力成本、时间成本等会比较大。所以比较明智的做法就是去租用第三方的数据存储服务器,使用他们提供的数据库服务等,比如国内比较主流的阿里云、腾讯云、百度云等。但是一直以来,数据拥有者默认第三方数据存储服务是可信的,不会篡改数据、不执行客户端的指令或者执行错误的指令等。

但是近几年数据管理的发展趋势,开始更多的去考虑以前或者说当前的数据外包行为在不可信的环境中是否还能正常的工作。然后在节点不可信的架构中,比较主流的共识协议就是PBFT。

在这里插入图片描述

但是这篇论文中他并没有使用PBFT相关的协议,他给出的一个说法就是,PBFT在不超过三分之一的副本出现故障时,才能保证容错能力。而在相对开放的数据架构中,存在数据异构、服务器横向扩展等情况,所以他觉得在这种场景下,使用PBFT不现实。

这边他提出了另一种方案,审计。其实在我看来,审计的方法就是一种offline的方法吧,或者说类似delay验证工作的方法。就是在数据查询、数据更新发生之后,后续的审计进程去分析各个服务器的日志,来判断是否有错误的行为发生,但这也就涉及到,怎么保证日志内容不可篡改。

Contribution

在这里插入图片描述

这篇论文的贡献主要是两点,首先是提出了一个在不可信架构中分布式事务的原子提交协议TFCommit,他是在2PC的流程基础之上,增加了密码学的方法,主要是签名,来建立一个可验证的分布式事务执行协议。后面会详细介绍他的工作流程。另一个就是使用TFCommit协议,构建了一个在不可信架构中进行数据管理的系统Fides。

Details

Cryptographic preliminaries

在这里插入图片描述

这里我们先看一下这篇论文主要使用到的两种密码学方法,第一个就是默克尔树,这个大家肯定都很熟悉了,二叉树的结构,叶子结点是各个数据的哈希值,然后向上,两两拼接,继续做哈希操作,最后得到一个根节点。然后数据拥有者或者可信服务器去存储这个根哈希值,后续的数据操作中,比如客户端要从第三方数据库查询a的值,那么第三方还需要提供相应的VO,就是从叶子结点ha到根节点路径中的各个兄弟节点,然后可信服务器或者客户端使用之前存储的根哈希值去验证第三方数据库返回的a的值是否正确。

在这里插入图片描述

然后第二个密码学方法就是签名,他使用了集体签名的方法。这边我并没有深入去看这个签名算法的数学原理,他能达到的效果其实和多重签名一样,对于一份文件,所有参与者通过签名的方式证明说自己同意这份文件,然后多个签名会被聚合成一个签名,后续验证的时候,比如要验证服务器A是不是签名了,只需要用他的公钥进行验证即可。

在这里插入图片描述

这边我们看一下生成一个集体签名的流程,首先要知道一点,就是这个签名方法,是需要有一个leader的,其实就是有一个coordinator来引导其他节点,完成签名操作。比如这边有一个文件R,需要大家签名,那么这个leader就会想所有的其他节点发出一个Announcement请求,其中包含了这个需要签名的文件,然后收到这个请求的节点就会根据规则去判断自己是否同意这一份文件,然后生成一个随机数,返回给leader(就图中的commitment步骤),leader会整合所有随机数,其实就是加和操作,然后使用加和得到的数对这份要签名的文件进行一个处理,然后在challenge步骤中,把处理后的数据再发送给各个节点,各个节点会使用刚才发出去的随机数进行一次验证,看leader是否正确的用该随机数对这份文件进行了相应处理,然后使用自己的密钥进行签名,再发回给leader,就是图中的response阶段。最后,leader会整合所有的签名,生成最后的集体签名。而这个集体签名,用某个参与者的公钥就能证明他是否对这份相应的文件进行了签名确认。

Components & Overview

在这里插入图片描述

接下来我来讲一下Fides的整体架构以及客户端与服务器进行交互的流程。
我们先看在Fides的架构中,一台服务器的组成细节。其实如果是单纯的数据库存储服务器,那么他就只有datastore就数据库系统,另外的,为了支撑他的TFCommit协议,还额外增加了事务执行模块(这个模块主要用来执行一个事务中的数据读写)、事务提交模块(这个模块的话,主要就是负责执行他的TFCommit协议,完成事务的原子性提交,和日志记录的添加)以及一个可不篡改的日志记录,可以看到他是链状结构,其实一个块中记录的就是事务的内容,在完成签名操作后,添加到日志链中,通过前一个块的哈希值串起来,日志这边我后面会细讲,前面提到了,他使用的是审计的方法,也就需要有日志记录来让审计进程进行审计,所以这里就需要在所有的数据服务器上维护同一份日志记录,供审计进程使用。这边后面会细讲他的日志添加流程。

在这里插入图片描述

然后我们看一下Fides的整体架构,他这边的话,可以看到,就是客户端需要执行一个事务,这个事务中涉及的数据,可能来自不同的表,或者库,因为数据会进行分库分表嘛。所以从图中可以看到,客户端同多个服务器进行了数据的读写操作。然后,在完成数据读写后,会有一个end的请求,他只会发给coordinator,然后由coordinator去协调其他的所欲服务器,完成这个事务的提交。

Client interactions

在这里插入图片描述

接下来我们来看一下客户端执行一次事务时,与服务器之间的交互过程。首先,客户端将begin tx的请求发给与该事务中的数据相关的服务器,注意,他的事务begin请求是发给这些数据所对应的服务器的,感觉他这张图不够严谨。然后在第2步,客户端构造相应的读写集请求,同样发给数据相对应的服务器,然后各个服务器,对于读请求,就返回相应的数据,对于写请求,则会被缓存在事务执行层中,等待后续的原子提交完成后,才会持久化到数据库中。所以,到目前为止,步骤1,2,3是客户端与事务中的数据所在服务器之间直接进行的。

然后,步骤4,客户端在完成数据请求后,发出一个结束事务的请求,这个请求,就只会发给coordinator,让他来协调所有的服务器,注意,这里是所有的服务器,即使是与本次事务涉及的数据无关的服务器,也要参与进来,因为需要所有节点记录日志嘛,细节的内容后面会讲。收到结束事务的请求后,coordinator就回去协调所有的服务器,完成原子提交的流程,也就是这边的步骤5,这里就开始涉及论文的TFCommit协议了,后面细说。然后完成原子提交流程后,所有节点把这次事务的内容写进日志链中。最后,刚才的写请求是被缓存着的,这里再持久化到数据库中。然后这个事务就结束了。

2PC

在这里插入图片描述

我们先来看一下传统的2pc,他是在可信的假设下进行工作的。比如有个分布式事务T1,需要完成commit操作,这里就有一个coordinator来协调,coordinator在收到end tx的请求后,就向所有节点发出
Getvote请求,这些节点选择commit或者abort这个事务,然后通过vote请求恢复给coordinator,coordinator整合大家的结果,如果都commit,就commit,如果有人abort那就abort

在这里插入图片描述

但是如果节点不可信,单纯使用2pc,可能会带来哪些问题呢?比如这些参与vote的节点,他可以投commit票,但是本地进行abort;还有就是coordinator,他可以在最后的decision阶段,给一部分节点发送commit的结果,给其他节点发送abort的结果。

TFCommit

在这里插入图片描述
在这里插入图片描述

针对上述问题,论文就提出了一种方法,那就是在2pc的基础上,添加集体签名的流程,然后所有节点配合存储签完名的日志,达到的效果就是如果有节点做出不正确的行为,审计进程可以通过日志分析,拿到相应的证据。

其实就是结合了2pc的原子性和签名的可验证性。接下来就说一下TFCommit协议的具体流程。

在这里插入图片描述

在讲TFCommit协议之前,有必要向了解一下针对一个事务需要记录的字段,论文中的讲述是基于一个块中一个事务进行的。我们来看一下具体的字段,首先就是事务的id,因为会有多个client执行事务,所以他的这个id需要保证全局有序,单调递增,可以使用类似Lamport clock的时间戳。然后就是读集和写集,其中每个数据,都有相应的最近的一次读时间戳和写时间戳。另外还有写操作涉及的服务器的默克尔根哈希值,这个根哈希值是使用相应的写值进行计算得到的,其实就是为了后续的验证,验证相应的服务器是否有正确的进行数据更新。然后就是decision字段,标识本次事务是commit还是abort。还有前一个块的哈希值,最后就是所有服务器的集体签名。这些字段是在执行TFCommit协议的过程中一个一个被补全的。

在这里插入图片描述

这边开始讲TFCommit的流程,这里我先说明一下他的每个步骤的标识,左边这个对应2pc中的步骤标识,右边则对应集体签名中的步骤标识。首先,就是客户端向coordinator发起一个end tx的请求,其中的请求信息包含了,事务id,读集和写集;然后coordinator会添加上一个区块的哈希值,然后发给所有服务器,对应的就是2pc中的getvote,集体签名中的announcement;然后各个服务器,服务器在这个阶段,一方面就是选择commit或者abort(2pc中的步骤),另一方面就是生成一个随机数返回给coordinator,为后面的签名作准备(对应集体签名的步骤),其中包含了与这次事务无关的服务器以及相关的服务器,其中相关的服务器又分成两种,一种是仅仅执行读操作,另一种就是执行写操作。然后执行写操作的服务器,他还需要使用那个更新值,去计算一个新的默克尔根,添加进相应的字段中,最后,所有的服务器把数据返回给coordinator(对应2pc的vote和集体签名的commitment);然后coordinator整合服务器返回的数据,主要就是整合默克尔根哈希值,因为可能有多个服务器上执行了写操作嘛,所以就有多个根,还有就是根据commit和abort的投票给出一个决策;然后这次事务所需要的字段到这里基本都齐了,但是差最后的签名,所以coordinator再把整合好的数据发给各个服务器,让他们签名(对应集体签名中的challenge);服务器收到challenge请求后,经过相应的确认后,使用其私钥进行签名,返回给coordinator;最后,coordinator整合签名,生成最后的集体签名,至此,这个区块就完整了,通过decision请求,通知所有的服务器把这个区块添加到本地的日志链中。

Merkle Tree

在这里插入图片描述

这里我再补充一下默克尔树在数据外包中的一个应用场景,它主要解决的一个问题就是去验证第三方数据库有没有按照客户端的指令正确的进行值更新。举个例子,这边客户端要更新b的值,给b加上100,但是数据库是不可信的,他可能不执行这个更新,或者更新成一个错误的值。那这种情况,我们怎么去保证说,第三方数据库正确执行了客户端的数据更新请求?

在这里插入图片描述

这就是默克尔树的一个主要应用场景了,我们来看ICDE2013中的一篇论文中的方法,他在事务的层面上应用了默克尔树。右边这个是数据拥有者,他把他的数据外包给了左边的第三方数据数据库,上面这个是客户端,他请求这个第三方数据库,进行事务执行,其中包含了写操作,然后要求第三方数据库在完成数据更新后,重新计算默克尔根哈希值,返回给客户端,然后客户端会把这个事务的细节,以及相应的根哈希值发给数据拥有者,数据拥有者可以对此进行验证,第三方数据库是否正确进行了数据的更新。

但是这个方案有几个缺点,比如你需要可信的组件或者说可信的节点,去做验证工作;还有就是这种模型只适用于单个数据库的场景。

audit process

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

最后,我来讲一下他的这个审计是怎么进行的。他的这个审计进程,就是给出了几点效果说明吧,他就是一种offline的检测方法,但是能够保证检测出相应的错误行为。他就是基于上述日志链,利用其不可篡改、可验证的效果进行审计。

在这里插入图片描述

他的审计主要针对两种,一种就是不正确的读,也就是第三方数据库返回了不正确的值。这里他的检测方法就是,比如第10个块,他记录了客户端的一个读请求,然后服务器返回的是1000,那么审计进程就会根据这个上一次写的时间戳ts-88去确认,之前是不是将x的值更新为1000了。

另一种呢,就是针对不正确的写,他的验证方法就是使用默克尔树的方法了,比如还是第10个块,这个事务中更新的x的值,那么审计进程就是去找对应的服务器要x的VO,进行验证。

Fides performance

在这里插入图片描述

公众号

  • 关注公众号,即时接收关于Java的技术分享!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JiangNanMax

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值