被纳入新基建的区块链,以数据不可篡改、可公开监管、便于查证的特性,广泛应用于有多方参与的系统中,为多方交互的信息(行为、数据等)提供可靠的存证。那么,在信息上链接受公开监管的同时,能否为信息提供隐私保护呢?隐私保护的数据又如何能验证其可靠性呢?腾讯云区块链使用同态加密、零知识证明、可信计算等技术,为区块链上数据隐私和行为可靠性提供了多方位的保障,并且提供了对国密算法的支持,在金融、政务等场景中可以选择适配SM2-SM3国密证书套件,完美对接国标、行标。那么腾讯云区块链究竟是怎么做到同时兼顾隐私性、可靠性的呢?
“ 术语小课堂:隐私性:我有一个值,但我不告诉你是多少。可靠性:我有一个值,我向你证明并且证明是我的。”
01—
链上的交易场景
以链上交易为例,有三种能兼顾隐私性和可靠性的交易方案:同态加密(HE)、零知识证明(ZK-Proof)、可信计算(TEE)。如Fig. 1所示的转账场景是区块链上常见的交易场景。在如Bitcoin、Ethereum等公有链中,这类交易是明文储存在链上的,也就是说任何人都可以通过区块链提供的查询功能获得任意账户的余额、资金动向等信息。
Fig. 1 链上交易:从账户 转账到账户
在这笔交易中,需要公开审计的是 ,而需要保护的信息也正是 、、 、 、 。如何在证明 这个关系的同时,不能泄露 、、 、 、 这几项账户、交易信息呢?如果直接把账户余额 、 和转账金额 加密了,要如何在链上对新密文进行公开的验证呢?
02—
链上的交易场景
举个例子,我存在银行的余额可进行加密,银行也不知道密钥,这样我的余额是保密的;但同时,如果我消费了10块钱,银行能基于我的加密余额减掉相应的钱。这就相当于保护隐私的情况下,执行交易。而这就是同态加密。
同态加密算法很多小伙伴都接触过甚至使用过。这类加密算法具有将密文的运算映射到明文的四则运算的特性。使用同态加密可以直接对密文进行运算,以改变隐藏在密文中的明文。
2.1 同态加密简介:如何选择同态加密算法?
“ 符号小课堂: : :是加密算法,为明文原文,为加密后的密文。 : :是解密算法,为密文,为解密后所得明文。 、、 :密文的同态加法、减法、乘法运算符”
根据算法所支持的同态运算,同态加密的能力各有不同。常见的、得到更多关注的同态运算是四则运算:
2.1.1 对加法同态:(加法与减法在现有算法的数学结构中是同类型的运算)
“ 密文与密文相加: 密文与明文相加: 密文相反数: 密文与密文相减: 密文与明文相减: ”
2.1.2 对乘法同态
“ 密文与明文相乘: 密文与密文相乘: ”腾讯云区块链同态加密同时支持了Paillier公钥加密与Lattice加密算法。
加法同态最容易支持,几乎所有同态加密算法都支持对加法的同态运算。而当前比较实用的算法中,Paillier公钥加密是除了支持对加法同态之外还能支持密文与明文相乘的同态加密算法。而全同态的能力,也就是对加法、乘法甚至除法的同态运算都支持的能力,则多见于基于Lattice这种数学结构设计的加密算法中。而基于Lattice的算法是post-quantum的,也就是说,即使在使用量子计算的环境中,这些算法仍然是安全不可暴力破解的,但这些算法本身的耗时也非常高。
Paillier这个基于DCRA假设 (decisional composite residuosity assumption) 的算法,每秒可以计算上万次同态加法(上次作者亲自benchmark是每秒15000次:在普通Linux系统上的Golang实现,安全等级在2048 bit),而基于Lattice的BGV算法 (Brakerski-Gentry-Vaikuntanathan) 在相同安全性配置下每秒只能计算不到两次(benchmark:同环境同安全等级下大约每次需要700-800毫秒)。这也就是安全等级、功能强度与性能的永恒的权衡(trade-off)。
那么强大的全同态加密就没有用武之地了吗?其实对于每10分钟出个块的公链,800毫秒的计算速度还是可以接受的。而在支持并要求快速出块的场景下,我们还是选择Paillier,毕竟兼顾了性能与可靠性。
Paillier在各种语言中都有开源实现,一部分实现是已经受过大规模使用的洗礼。而基于Lattice的post-quantum算法们应用并不广泛,而亲测除了效率之外,还是非常容易上手使用的。HElib是个C实现,与其他语言的项目兼容性喜人。
2.2 处理同态加密中的负数
密码学算法通常使用有限的数域作为明文、密文、签名、公私钥等的取值范围,而且通常是循环的有限数域,比如 生成的整数域就是{ }这个集合,但取值会循环, 会跳回数域的第一个元素 。这类数域经过平移可以使元素变成一半正一半负。例如 生成 { },他与 生成的数域在数学结构上是等效的,但在实际应用中就引入了负数,可以支持更多场景,因此变得更实用了。
同态加密这类密码学算法在使用中也可以通过平移数域的方法,将原本只包含正整数的明文取值范围变成包含负整数的取值范围,并且这个改动也只需要在加密、解密算法的实现中做一些工程改动即可。常用的做法是,对于一个 生成的域,假设一个值为 ,如果 <mjx-container jax="SVG" role="presentation" tabindex="0" ctxtmenu_counter="63" data-formula="y\mod n ,则直接使用 ;否则计算得到一个负数。这种映射方式可以保证明文、密文的计算是对应的,不会出现判断边界导致的错误。
2.3 处理同态加密中的小数
前文提到的这些同态加密算法,他们距离现实还有一个大障碍——原算法为整数设计。这也可以理解,因为这些密码学算法全是基于数论的,他们所依赖的数学理论中,数学结构都是以整数来表达的,对整数有天然的兼容性,而对小数就不是那么友好了。那么在使用时,我们就需要对这些算法做一些兼容性的处理。其实这些处理都比较直观,而且都是从工程上来解决,并不需要从理论上解决。
2.3.1 保留小数位数固定的场景:
例如记录金额的数据,通常保留两位小数。这种场景中,加密前对所有数据都乘100化成整数,解密后除以100取回原本的小数即可。只要不涉及密文与密文的乘法运算,这种方法就可以解决小数的兼容问题。
2.3.2 保留随意位数小数:
将数据的整数部分与小数部分拆开进行加密,在解密后重新组合。使用这个方案时,要注意为保存小数部分的数据分量保留一部分缓冲位数,当密文计算导致进位到整数部分时,可以暂时将这部分整数值保留在这个密文中。用 Paillier 算法为例子,明文长度允许为 2048 bit,作为小数分量的明文可以考虑使用 1024 位表示小数,另外 1024位预留给可能进位的整数 (实际情况可能保留64位整数就很足够了)。
2.3.3 准确计算结果:
在需要准确保留运算结果的场景中,需要将计算中涉及到的小数化成分数,并把分子、分母拆开分别加密。计算时,以 为例,需要在密文上计算 和 作为结果的密文,解密后计算 。这种场景需要全同态算法支持。
2.4 使用同态加密保护交易隐私
回到链上交易的问题,引入同态加密后,交易过程变成Fig. 2所示。
Fig.2 同态加密保护的链上交易
如图中的计算,对等式 的验证可以转化为密文上的验证: 。如此,链上数据全程都是密文,却并不妨碍公开监管。
03—
运算合理性怎么保证——零知识证明
我不给你展示身份证,但是我要向你证明我已经年满18岁,这时候应该怎么办呢?
在上一部分,我们讨论了使用同态加密来保护链上数据隐私又能提供公开监管的方案。如果在交易场景中,我们对账户余额做出一定的限制,比如 、 都不可以小于 ( 是有可能小于 的),那么同态加密提供的方案就不能再交易执行之前判断这个交易是否符合限制条件了。这时候,我们可以引入另一个密码学算法体系——零知识证明。
简单来说,零知识证明就是,我有一个 ,我需要向你证明 满足的一个关系,例如 <mjx-container jax="SVG" role="presentation" tabindex="0" ctxtmenu_counter="55" data-formula="f(x) 或者 ,我不告诉你 的准确值还要说服你 满足的一个关系,例如 <mjx-container jax="SVG" role="presentation" tabindex="0" ctxtmenu_counter="65" data-formula="f(x) 或者 ,我不告诉你 的准确值还要说服你 满足这个关系。一个直观的例子如Fig.3所示。证明者P知道山洞中密道的存在,而验证者V并不知道。P先随机选择A、B两条通道之一进入山洞中,V来到洞口,随机指定A、B之一要求P从指定通道走出山洞。多次实验后,V被说服了P知道密道这一事实,但V仍然不知道密道在哪里。而在区块链交易场景中,我们需要的效果是所有人都被说服 0" style="max-width: 100%; box-sizing: border-box !important;"> 和 0" style="max-width: 100%; box-sizing: border-box !important;"> 这个事实,却不知道 、 的具体值。在这部分,我们会详细介绍如何使用Pedersen承诺、Bulletproofs零知识范围证明来达到这个目标。
“ 注:在这部分的算法里出现的大写字母变量为椭圆曲线上的点,小写字母变量为数值。除法符号表示的是模拟运算。 ”
Fig.3 密道的零知识证明
3.1 Pedersen承诺(commitment) 算法[3]
承诺算法是一种提供数据绑定及数据保密的算法,有两个基本接口:制作承诺 (commit)和打开承诺 (open)。
:输入一个明文数值 和一个随机致盲因子 ,返回一个对 的承诺 。其中,致盲因子也称为opening,可以视作对称签名算法的私钥或者加密算法中的解密密钥。
:打开承诺是验证一个承诺 是否与其宣称绑定的值 真实绑定。 是制作承诺时所使用的致盲因子。
承诺具有两个属性:隐藏性 (hiding) 和绑定性 (binding)。
- 隐藏性:给出一个承诺 ,无法算出其中绑定的数值 。更高的安全性则要求敌手选择两个数值,由被挑战者任选一个制作成承诺,而敌手猜出正确数值的概率不高于 。
- 绑定性:给出一个承诺 及其绑定的数值和致盲因子对 使得 ,无法找到另一组 使得 。
承诺的隐藏性可以为链上数据提供隐私保护,而绑定性则可以为保密数据的链上公开监管提供可靠性保障。
3.1.1 Pedersen承诺算法详情
Pedersen承诺是一个基于椭圆曲线 (EC) 的密码学算法。我们取用椭圆曲线加法群上的两个随机基点 、 作为公共参数。
:计算 作为 的承诺。
:判断 ,若等式成立则返回 ,否则返回 。
3.1.2 Pedersen承诺的同态运算
Pedersen承诺支持部分同态运算:承诺+ 承诺,承诺 + 数值,承诺 – 承诺,承诺 – 数值,承诺的相反数,承诺 数值。
假设有两个承诺 、 ,和另一个数值 。
- 承诺 + 承诺:已知 ,求 的Pedersen承诺 在 中,绑定的数值变成了 ,而致盲因子opening变成了 。
- 承诺 + 数值:已知 和 ,求 的Pedersen承诺 在 中,绑定的数值变成了 ,而致盲因子仍然为 不变。
- 承诺 – 承诺:已知 ,求 的Pedersen承诺 在 中,绑定的数值变成了 ,而致盲因子变为 。
承诺 – 数值: 在 中,绑定的数值变成了 ,而致盲因子仍为 。承诺相反数: 在 中,绑定的数值变成了 ,而致盲因子变为 。- 承诺 数值: 在 中,绑定的数值变成了 ,而致盲因子变为 。
3.2 Bulletproofs零知识范围证明(zk-range-proof)算法[4,5]
Pedersen承诺算法只能保证数值运算正确地在密文 (承诺) 上进行,而不能给运算结果任何限制。而在特定场景中,例如转账——我们要求转出账户的余额要大于转出值,也就是运算结果需要为非负数。零知识范围证明可以提供在不公开数值的情况下证明一个数在某个特定范围内的能力。
零知识证明具有三个特性:零知识、完备性和公正性。
在Bulletproofs零知识范围证明中,要证明的基本命题是数值 〖μ〗 ,其中 是需要隐藏的命题组件, μ 是一个大于1的正整数,实现时为了方便,通常取 μ ,零知识体现在从证明、验证过程中无法得出任何一个证明π所证明的命题中的 的值。
Bulletproofs也是一个基于EC的算法,并且使用Pedersen承诺作为证明的一部分用以绑定及隐藏 。其基本设计如下:公共信息: μ 证明者的秘密输入:
1. 验证者随机选择 ,计算 ,其中 。验证者把 发送给证明者。2. 证明者把 转换为 bit 流的形式 ,其中 。证明者随机选择 并计算 。注意 。
证明者现在需要证明 ,而不公开 。这种类型的零知识证明可以使用 protocol来进行。以上的算法步骤都是需要验证者与证明者实时交互才能完成的。我们可以用 Fiat-Shamir 启发式把交互式的证明转化成非交互式的证明,也就是证明者算出一个非交互式证明之后,任何人都能在没有证明者协助的情况下进行验证 (类似签名中的验签)。关于 protocol 和 Fiat-Shamir 协议的基本概念,可以参考下面的知识小课堂。
证明输入中的 其实是 的一个 Pedersen 承诺。在转换成非交互式证明后,验证过程主要验证了以下几点:
证明中的与承诺中绑定和隐藏的是同一个值; 证明中的在范围内。
多个不同的证明(除了致盲因子外,证明还有其他随机因子)可以对应同一个承诺,而多个不同的承诺不可能与同一个证明对应通过验证。
3.3 任意范围的证明
这个部分,我们讨论如何把证明范围 扩展到任意范围 。要证明 ,我们可以证明 。结合 Pedersen 承诺的同态运算,我们可以很容易地通过两个非交互式证明完成任意范围证明。
回到我们最初的交易场景中,链上数据以 Pedersen 承诺的形式上链,配合一个证明承诺中明文大于零的 Bulletproofs 证明,其他参与者就可以在不知道明文的情况下也能被说服改明文大于零了。计算时,利用 Pedersen 承诺的同态性质,其他链上参与者可以很容易地看到 这个关系,并且能通过 Bulletproofs 的证明确认 与 都大于零。
04—
把计算逻辑放进保险箱——可信计算(TEE)
前面两个小节为大家介绍了两套解决区块链上机密交易的密码学体系。密码学算法提供的安全等级是比较高的,但是他们也有他们的缺点:兼容性问题和运算效率较低的问题。面对安全等级、功能性和性能永恒的trade-off,我们还有工程+密码学的解决方案——可信计算。
相较于密码学算法,可信计算虽然无法在理论上严谨地被证明安全 (推导到与NP问题等效),但是在现实中攻破可信计算环境是非常困难的,而且他具有兼容性好、运算灵活、运算效率高的优势,确实是一个非常优秀的密码学算法替代品。
可信计算本质上是用硬件来构建一个反沙箱环境,外部(包括OS)不能自主访问或更改可信硬件内部的软件、数据。结合一些简单的密码学算法,可信硬件可以与外部进行安全交互,以实现在可信环境中处理敏感数据,然后以密文形式取出并提供可靠性认证的目的。
举个例子,腾讯计费业务沉淀的风控系统,积累了大量精准的风控模型能力,如果外部合作游戏厂商希望借助于腾讯的风控模型提高业务风控效果,但又不希望将用户信息的敏感数据对外暴露。这是就可我们通过可信计算确保风控模型与用户信息在可信域内处理,并结合区块链,保证交互留痕、可追溯以及透明性。 当下主流的可信硬件有三种:
SGX (Software Guard Extension):Intel的处理器扩展芯片,提供有限的安全指令集,有较强计算能力,在应用层为软件加固,本身无存储能力。 TPM (Trusted Platform Module):TCG (AMD, HP, IBM, Intel, MS联合项目) 的可信计算模块,最先启动,可用于从硬件到软件的认证链,本身拥有较弱的计算、存储能力。 TrustZone:ARM架构中的可信计算扩展模块,非公开架构,与SGX行为相似。
由于 SGX 具有较强的计算能力,可以兼容的运算逻辑灵活多样(几乎可以是图灵完备的),所以我们以 SGX 为介绍主体。SGX 设计初衷是保护运行环境不被信任域外的软硬件读写。这里的敌手包括本地环境中的 OS、hypervisor、BIOS、firmware 等,即使同系统中其他软件受到提权攻击,也不会影响信任域内。
Fig.4 攻击面对比:左图黄色虚线框中为一般运行环境的攻击面,右图黄色虚线框中为SGX环境中的攻击面
SGX 硬件中有固有的两个私钥:root seal key 和 root provisioning key,分别用于衍生加密密钥和认证可靠性。这两个私钥是使用可编程只读存储器保存的。可编程只读存储器在烧制过一次之后无法更改,而且在 SGX 中无法被外部访问。SGX 的隔离原理如Fig. 5所示,其中 Enclave 是运行外部传入的逻辑的一个资源分片。
Fig.5 SGX的隔离、隐私保护、认证
Provisioning key 的使用类似证书,而Intel是一个证书发行 CA,会为所有 SGX 模块的 provisioning key 颁发一个独立的证书。Seal key 是绝对只存在于 SGX 内的,且每一个 SGX 硬件拥有一个唯一的 seal key (当然随机数存在碰撞,但概率极低),用于生成后续所有加密用私钥或密钥对。外部通过 provisioning key 的证书体系验证 SGX 的可靠性:是否为可信环境,Enclave 中的运行逻辑是否未被篡改。内外通信时,使用 seal key 衍生的密钥加密。Provisioning 和 seal 两个机制分别保证了可信计算的可靠性 (包括运行逻辑不被篡改、结果被认证) 和隐私性。
4.1 使用可信计算保护交易隐私
那么如何把可信计算 (TEE: trusted executionenvironment) 应用到区块链的机密交易场景中呢?首先,链上数据由 TEE 加密、签名后,以密文+签名组合的形式上链,也就是说 、 账户余额的密文和签名存于链上。在交易时,外部调用方使用 TEE 的公钥加密 并将密文传入 TEE,TEE 上链取得 、 的密文和签名,在验证签名正确性后,TEE 使用自己的私钥解密 、、 ,计算出 和 ,对 和 加密、签名认证后,输出密文及签名到链上。公开监管的区块链参与者可以通过验证 TEE 签名来验证链上数据是否可靠。链上交易的有效性需要由部署于 TEE 内的逻辑来校验,如果不符合,该逻辑需要拒绝交易。
4.2 链上链下的桥梁
TEE 也可以用于链上链下的互联。一些场景中需要把计算逻辑部署在链下,而无法以智能合约的形式部署于区块链上。例如一些国家或地区的数据不能跨地区传到别的地区的区块链上,只能在本地区对数据加工后传出。这时候可以把数据处理逻辑部署到TEE 中,由 TEE 收集数据计算后,对结果进行签名认证再传到跨地区的区块链上,区块链节点只需要通过验证签名、验证TEE的可靠性来决定是否接受该上链请求。
05—
安全领域自主可控之光——国密算法
国密算法是一套包含对称加密、非对称加密、签名、哈希等基本密码学算法的,从算法设计、理论推导到开发实现都是中国自主研发的密码学算法集合。过去,商用密码学算法是美国主导的。从理论到算法实现都是境外学者、工程师完成的。对于关系到安全的密码学算法是否有设计上预留的后门,我们并不确定。在诸如政务、军事、金融等敏感领域,使用别人的算法存在敏感信息泄露、重要信息被篡改的风险,因此国家推动自主的密码学算法势在必行。
腾讯云区块链中使用的密码学算法,除了区块链本身的哈希和签名外,更重要是在通信过程中的证书上。腾讯云区块链平台基于自研的国密解决方案,提供了对国密证书的支持,在区块链节点与节点、区块链用户与节点间的通信中同时支持使用传统 ECDSA-SHA256 证书和国密 SM2-SM3 证书,在证书切换上做到配置时用户自选、使用时用户不感知。
目前国密算法的支持一方面符合了金融、政务以及各类企业的安全规范要求,另一方面可帮助我国区块链技术实现安全上自主可控、不受制于人。
06—
区块链密码安全特性的产业应用
说了一大堆,那么这些在腾讯云区块链中使用到的安全技术究竟离我们的实际生活有多近呢?前文中提到的使用同态加密、零知识范围证明实现的机密交易,使用可信计算实现的多方计算、链上链下互通究竟要怎么用呢?以下我们介绍一些实际场景的应用。
在银行、金融体系中,使用链上机密交易,通过将账户信息加密后放到区块链上存证,交易请求中也对交易额进行加密,以保护资金流,那么配合同态加密或零知识证明算法,可实现对链上密文的计算和对计算结果的验证,达到交易信息保密、交易事件可公开监管、交易结果可及时验证的效果。举个例子,公司 A 和公司 B 作为区块链分布式账本的参与方,可以将自己的账户余额等信息采用同态加密的密文形式存到链上。这样一来,A 向 B 支付一笔款项时,则可以通过同态运算来执行这个交易,并用零知识证明提供余额足够支付这次交易的证明,整个商业互动就可以在隐私保护中进行。
在广告投放的场景中,也可以用部署了可信计算的腾讯云区块链来安全地联合提取隐私数据中的可公开信息。广告归因是一个典型的涉及多方数据共享的场景。这个场景主要参与方包括广告投放商和广告平台:广告投放商拥有用户购买其产品或服务的交易信息,而广告平台拥有用户对投放商投放在平台上的广告的浏览、点击信息。在现行商业模式下,广告投放商会根据浏览、点击了广告的用户是否购买产品或服务的情况来计算一个广告转化率,计算公式是: 转化率浏览过广告且购买的用户量浏览过广告的用户 。要得到转化率数据,就需要得到广告投放商侧购买过产品的用户集合与广告平台侧浏览过广告的用户集合的交集。广告投放商与广告平台可以使用第四部分提到的链上链下互通的机制把各自数据的存证放到区块链上,而不公开数据本身。需要计算转化率时,可以通过可信计算环境来验证链上存证与链下实际数据,并在实际数据上进行计算得到结果。整个过程不会泄露链下数据。
这期我们就介绍到这里。区块链的安全应用场景还有很多,希望这次的分享可以在思路上帮到大家。
[1] Schnorr, “Efficient identification and signatures for smartcards”, Crypto 1989 [2] Fiat, Shamir, “How to Prove Yourself: Practical Solutions toIdentification and Signature Problems”, Crypto 1986 [3] Pedersen, “Non-interactive and information-theoretic secureverifiable secret sharing”, Crypto 1991 [4] Camenisch, Chaabouni, Shelat, “Efficient Protocols for SetMembership and Range Proofs”, AsiaCrypt 2008 [5] Bunz, Bootle, Boneh, Poelstra, Wuille, Maxwell, “Bulletproofs:Short Proofs for Confidential Transactions and More”, S&P 2018
|