比特币在数据安全领域的应用(一)
首页 专栏 安全 文章详情
0

比特币在数据安全领域的应用(一)

Ljzn 发布于 11小时前

你有没有遇到过这样的场景,公司需要配置一个内部服务,为了方便调试,暴露了一个公网的接口。同时为了保证安全,为这个接口设置了 token 验证。只有小组的成员知道这个 token。很明显,这里存在安全隐患,小组的成员有可能泄露 token。为了可追查,决定为小组每个成员分配不同的 token。然而总有一个运维人员可以获取到全部的 token,所以你们决定采用非对称加密,小组每个成员自己在本地生成一个密钥对,提交公钥到一个白名单里,自己保存私钥。每次调用接口的时候,使用私钥对请求内容进行签名,然后服务器对签名和白名单里的公钥进行验证。到这一步,我们实现了 token 和身份的绑定。然而,依然有问题存在:是否有一个最高权限可以任意添加公钥到白名单里,之后再删除,并且将历史记录一并删除?为了防止这种事情发生,我们可以在每次修改白名单的时候,都使用邮件或者 IM 通知小组的全体成员,这样,即使服务器上的记录被删除,小组成员依旧保留有本地的记录。问题又来了,如果不知道是什么原因,某个小组成员出示了一封邮件,里面是白名单的一次修改记录,而其它成员并没有这封邮件,那么如何判断这个记录的真实性呢?假设我们确信邮件发送的服务商是可靠的,服务商只有在收到白名单被修改的消息的时候才会去发送这封邮件,那么这封邮件应该是真实的。但假如有人伪造了 “白名单被修改” 的消息,发送给邮件服务商呢?我们发现,在每一个环节,都有可能出现漏洞,

PKI系统(公钥基础设施)无法回避的问题是如何防止记录被删除,以及如何验证异地恢复的数据的真实性。只要有迹可循我们就可以找到真相,问题是删除记录,伪造记录,对于黑客或者是内部人员来说都是可以办到的。为了保证记录不被删除,公司必须采用第三方服务,而且最好是大公司的服务,因为大公司普遍拥有更高的安全保障。这并不意味着能够完全避免风险,比如之前的 GitLab 代码被删除,有赞删除商家订单数据等等。幸运的是,我们现在有了更好的方案,即区块链。你可能没有听说过区块链,但一定听说过比特币。作为一个点对点的电子现金系统,比特币自诞生以来的一直在不断产生新的交易记录,这些交易记录最早可以追溯到十一年前,而且每一笔交易发生的大致时间我们都可以通过哈希算法去验证。另外,在比特币的单笔交易里最大可以附带 4GB 的数据(OP_PUSHDATA4)。你可以把比特币理解为一个非常可靠的云服务公司,你可以在比特币上以增量更新的方式去做 CRUD,且每次操作的记录都是几乎不可能被删除的(会被分发到全世界的节点),即使被删除,只要本地留存有原始交易,以及交易的默克尔证明(merkleroot),即可验证交易的真实性,且无法在一段时间之后去伪造之前的操作记录。至于隐私问题也很好解决,把数据进行加密再发布即可,你可以把比特币当作一个硬盘来使用,如何解读数据,由代码里的业务逻辑去定义。

有人可能会说,这样并不能解决非法的数据被写入到区块链上,而且使用者需要自行通过本地的业务逻辑去验证交易中包含的数据的合法性,这需要耗费很多计算量。比如在我们上面提到的场景下,小组的每个成员提交了自己的公钥,然后用自己的私钥去签名自己要执行的操作,然后发送给接口,在这里也就是发送到区块链上。在这一步中,攻击者可以通过发送大量的非法消息,来消耗我们的计算量(对于每条消息我们都要验证签名)。尽管攻击者需要付出比特币交易手续费的成本,但随着比特币手续费越来越低,且我们的验证逻辑如果比较复杂的话,是有可能抵消掉这个成本的。

image.png

最简单的使用方式:由数据的消费者来验证数据的合法性

这种由数据的消费者来验证数据合法性的方式也被称为 “链下验证” 或者是 二层网络(layer 2)。在交易所中广泛被使用的稳定币 USDT 就是采用这种方式发行的。验证一笔 USDT 转账是否合法,是需要运行特殊的节点程序,这个节点程序会从第一笔 USDT 发行的交易追溯起,去判断每个地址在每个时刻的余额,以过滤掉那些“假币”。 那么,是否存在一种更好的方案,让不合法的数据从一开始就无法发布到区块链上呢?当然,是存在这样的方案的。我们把它称为一层网络(layer 1)。比特币中内置了一个脚本虚拟机,每一笔交易,都需要由这个虚拟机来运行,得到一个 true 或 false 的结果,而如果结果是 false,这笔交易就不会被打包进区块里,换句话说,就不会出现在区块链上。而这种脚本语言本身是图灵完备的,它能够实现任何的验证逻辑。脚本的执行者是挖矿的节点,新闻里面常说的比特币矿工,他们所做的一部分工作就是执行接收到的交易中的脚本。当比特币网络中的复杂脚本越来越多,脚本的执行速度就会影响到矿工的收入,这时候矿工会逐渐增加在这方面的投入,例如采用 FPGA 甚至 ASIC 等专有硬件来执行比特币脚本。这样,执行一段脚本的成本就会显著降低,使得我们上面提到的那种攻击形式变得无利可图。

image.png

复杂的应用形式:在交易的脚本中实现验证逻辑。

目前,已经出现了能够编译到比特币脚本的高级语言,scrypt。它的语法与常见的高级语言并无太大区别,很快就能上手,在 vscode 编辑器中安装一个插件就可以使用了。

接下来我将分别使用 layer 2 和 layer 1 的方式,开发一个具有友好操作界面的,实现了文章开头提到的 token 权限转移的需求的应用。关注作者,方便第一时间收到推送。

本文中的 “比特币” 指包含区块 “000000000000000002f5268d72f9c79f29bef494e350e58f624bcf28700a1846” 的比特币数据链。
安全 比特币
阅读 49 更新于 11小时前
赞 收藏
分享
本作品系原创, 采用《署名-非商业性使用-禁止演绎 4.0 国际》许可协议
avatar
Ljzn

周一到周五,每天一篇老停更最新文章高赞文章

217 声望
48 粉丝
关注作者
0 条评论
得票 时间
提交评论
avatar
Ljzn

周一到周五,每天一篇老停更最新文章高赞文章

217 声望
48 粉丝
关注作者
宣传栏

你有没有遇到过这样的场景,公司需要配置一个内部服务,为了方便调试,暴露了一个公网的接口。同时为了保证安全,为这个接口设置了 token 验证。只有小组的成员知道这个 token。很明显,这里存在安全隐患,小组的成员有可能泄露 token。为了可追查,决定为小组每个成员分配不同的 token。然而总有一个运维人员可以获取到全部的 token,所以你们决定采用非对称加密,小组每个成员自己在本地生成一个密钥对,提交公钥到一个白名单里,自己保存私钥。每次调用接口的时候,使用私钥对请求内容进行签名,然后服务器对签名和白名单里的公钥进行验证。到这一步,我们实现了 token 和身份的绑定。然而,依然有问题存在:是否有一个最高权限可以任意添加公钥到白名单里,之后再删除,并且将历史记录一并删除?为了防止这种事情发生,我们可以在每次修改白名单的时候,都使用邮件或者 IM 通知小组的全体成员,这样,即使服务器上的记录被删除,小组成员依旧保留有本地的记录。问题又来了,如果不知道是什么原因,某个小组成员出示了一封邮件,里面是白名单的一次修改记录,而其它成员并没有这封邮件,那么如何判断这个记录的真实性呢?假设我们确信邮件发送的服务商是可靠的,服务商只有在收到白名单被修改的消息的时候才会去发送这封邮件,那么这封邮件应该是真实的。但假如有人伪造了 “白名单被修改” 的消息,发送给邮件服务商呢?我们发现,在每一个环节,都有可能出现漏洞,

PKI系统(公钥基础设施)无法回避的问题是如何防止记录被删除,以及如何验证异地恢复的数据的真实性。只要有迹可循我们就可以找到真相,问题是删除记录,伪造记录,对于黑客或者是内部人员来说都是可以办到的。为了保证记录不被删除,公司必须采用第三方服务,而且最好是大公司的服务,因为大公司普遍拥有更高的安全保障。这并不意味着能够完全避免风险,比如之前的 GitLab 代码被删除,有赞删除商家订单数据等等。幸运的是,我们现在有了更好的方案,即区块链。你可能没有听说过区块链,但一定听说过比特币。作为一个点对点的电子现金系统,比特币自诞生以来的一直在不断产生新的交易记录,这些交易记录最早可以追溯到十一年前,而且每一笔交易发生的大致时间我们都可以通过哈希算法去验证。另外,在比特币的单笔交易里最大可以附带 4GB 的数据(OP_PUSHDATA4)。你可以把比特币理解为一个非常可靠的云服务公司,你可以在比特币上以增量更新的方式去做 CRUD,且每次操作的记录都是几乎不可能被删除的(会被分发到全世界的节点),即使被删除,只要本地留存有原始交易,以及交易的默克尔证明(merkleroot),即可验证交易的真实性,且无法在一段时间之后去伪造之前的操作记录。至于隐私问题也很好解决,把数据进行加密再发布即可,你可以把比特币当作一个硬盘来使用,如何解读数据,由代码里的业务逻辑去定义。

有人可能会说,这样并不能解决非法的数据被写入到区块链上,而且使用者需要自行通过本地的业务逻辑去验证交易中包含的数据的合法性,这需要耗费很多计算量。比如在我们上面提到的场景下,小组的每个成员提交了自己的公钥,然后用自己的私钥去签名自己要执行的操作,然后发送给接口,在这里也就是发送到区块链上。在这一步中,攻击者可以通过发送大量的非法消息,来消耗我们的计算量(对于每条消息我们都要验证签名)。尽管攻击者需要付出比特币交易手续费的成本,但随着比特币手续费越来越低,且我们的验证逻辑如果比较复杂的话,是有可能抵消掉这个成本的。

image.png

最简单的使用方式:由数据的消费者来验证数据的合法性

这种由数据的消费者来验证数据合法性的方式也被称为 “链下验证” 或者是 二层网络(layer 2)。在交易所中广泛被使用的稳定币 USDT 就是采用这种方式发行的。验证一笔 USDT 转账是否合法,是需要运行特殊的节点程序,这个节点程序会从第一笔 USDT 发行的交易追溯起,去判断每个地址在每个时刻的余额,以过滤掉那些“假币”。 那么,是否存在一种更好的方案,让不合法的数据从一开始就无法发布到区块链上呢?当然,是存在这样的方案的。我们把它称为一层网络(layer 1)。比特币中内置了一个脚本虚拟机,每一笔交易,都需要由这个虚拟机来运行,得到一个 true 或 false 的结果,而如果结果是 false,这笔交易就不会被打包进区块里,换句话说,就不会出现在区块链上。而这种脚本语言本身是图灵完备的,它能够实现任何的验证逻辑。脚本的执行者是挖矿的节点,新闻里面常说的比特币矿工,他们所做的一部分工作就是执行接收到的交易中的脚本。当比特币网络中的复杂脚本越来越多,脚本的执行速度就会影响到矿工的收入,这时候矿工会逐渐增加在这方面的投入,例如采用 FPGA 甚至 ASIC 等专有硬件来执行比特币脚本。这样,执行一段脚本的成本就会显著降低,使得我们上面提到的那种攻击形式变得无利可图。

image.png

复杂的应用形式:在交易的脚本中实现验证逻辑。

目前,已经出现了能够编译到比特币脚本的高级语言,scrypt。它的语法与常见的高级语言并无太大区别,很快就能上手,在 vscode 编辑器中安装一个插件就可以使用了。

接下来我将分别使用 layer 2 和 layer 1 的方式,开发一个具有友好操作界面的,实现了文章开头提到的 token 权限转移的需求的应用。关注作者,方便第一时间收到推送。

本文中的 “比特币” 指包含区块 “000000000000000002f5268d72f9c79f29bef494e350e58f624bcf28700a1846” 的比特币数据链。