漫谈加密隐私

概述

加密,即将明文信息改变为难以理解的密文内容,使之不可读。只有拥有解密方法的对象,才能将密文还原为明文。

从古至今,密码学已有数千年的历史。从早期的古典密码,到近现代密码,再到未来的量子密码。加密手段也由早期简单的代替和置换,进化到现代数学方法,再到未来的量子性质。

本篇文章无意讲述整个密码学的发展史,而是聚焦于现代计算机应用中所涉及的加密方法和原理,漫谈 Web2区块链 涉猎的加密内容。

个人能力所限,如有缺漏错误之处,望指正。

PS:

现代密码学

原理

近现代以来,随着数学方法和的计算机科学蓬勃发展,为加密技术提供了新的概念和工具。一个重要的标志是香农的《保密系统通信理论》,将传统密码学推向了基于信息论的科学轨道。

近现代加密技术经历了无数次迭代,大体上可分为两类:对称密钥算法非对称密钥算法

对称密钥,即发送方和接收方采用相同密钥对明文进行加解密;非对称密钥则相反,它有两个公钥和私钥,分别用于加密、解密。

对称密钥可以任意选取,只要足够安全;而非对称密钥则是通过一系列NP问题生成的。如RSA利用大质数性质,ECC(椭圆曲线)利用离散对数问题。

简单来讲,P问题是在多项式时间内可以解出的;NP问题是在多项式时间内可以验证一个解的;P = NP意味着NP问题也是在多项式时间内可以解出的,而非对称密钥就建立在P != NP的基础上。

以RSA为例,一个大致流程可以理解如下:

  • NP问题 – RSA算法大质数分解;
  • 一个特解 – 两个因子和大质数,利用因子生成公钥、私钥;
  • 两个精致算法 – 可以利用公钥加密、私钥解密私钥签名、公钥认证
  • 黑客攻击 – 暴力分解大质数,拿到因子和私钥

弊端

  • 对于对称密钥加密来说,缺点在于密钥的分发,如何保证安全地分发到发送方和接收方手上;
  • 对于非对称密钥加密来说,缺点在于加解密的速度,如RSA算法每次加解密需要进行指数和取模运算,而对称密钥只需要做按位运算。

所以常见应用场景是结合两种方式,利用非对称密钥加密分发对称密钥,解决上述痛点问题。

Web2

HTTPS

在传统的Web2服务中,一个最常见的加密就是TLS加密,HTTPS = HTTP + TLS。

HTTP是明文传输的,这意味着在网络中所有中间节点都可以看到传输信息。为了保护敏感信息,我们采用TLS加密,使明文内容只对服务端可见。

TLS的一个大致流程如下:

1. 完成TCP握手后,客户端发起TLS请求,携带公开随机数、支持的对称加密方法、TLS版本、域名等信息;
2. 服务端返回证书、公开随机数、支持的对称加密方法;
3. 客户端验证证书有效性,解出服务端公钥,发送一个加密随机数;
4. 通过三个随机数生成对称密钥,加密之后的通信内容

还有面对银行等安全场景的双向验证,服务器端还需验证客户端证书,大致流程也类似。

整个过程有一个问题:要如何信任服务端返回的证书(公钥),而不是中间人攻击替换后的?

在网络的黑暗丛林中,我们需要一个权威机构(CA)来认证,这里就涉及到非对称密钥的另一个用途:私钥签名、公钥认证

CA通过它的私钥来证明证书的有效性,那我们如何确保正确拿到CA的公钥来认证呢?答案是它内置在操作系统或浏览器中,我们也可以手动增删。

最后为了保护这些CA的私钥不泄漏和降低泄漏后的影响面,我们把这些CA按层级划分,形成一个CA证书的信任链。

Signal

在C2C的场景中,我们也需要端到端加密,不过是服务端变成了另一个客户端,但我们不希望中间服务器有能力窃听通信内容。

你可能会有疑问:既然是C2C,那为什么我们还需要服务器?原因有很多:

  • 公钥的分发,中间服务器在这里相当于CA权威机构的角色,预防中间人攻击
  • NAT穿透,由于IPv4的局限性,我们大部分的地址是动态的内网地址,它是无法作为公网IP进行通信的
  • 信息缓存,历史信息保存 或 一方离线时也需要由服务器缓存相关信息,等该端上线时再进行分发
  • 信息转发,群组聊天中,需要中间服务器转发给其他成员,发送端只需发送一次到服务端
  • 垃圾信息过滤,中间服务器采用好友关系等机制限制垃圾信息洪流

PS:

区块链

加密货币

区块链上的虚拟货币也被称为 加密货币。加密属性从何而来?

个人所认为的加密不只是所谓的地址代替实名,而是更有意义的隐匿隐匿资产隐匿地址关系隐匿交易细节

很遗憾,目前主流的区块链本身并没有这一功能,它也不算是必需品,因此后面在区块链协议之上繁衍出了各种应用级产品:隐私币隐私合约,最后甚至是专门面向隐私功能的隐私链

在了解这些产品前,我们先来学习下区块链本身的隐匿性。如比特币和以太坊的帐户模型

小结下就是:区块链本身的隐匿性聊胜于无,基于UTXO模型的P2SH类型交易,有一定的隐匿性,可以暂时 隐匿接收者(地址关系),当花费这笔代币时,接收者还是会暴露。

零知识证明

在学习下面的加密原理之前,先要理解一个不可或缺的知识点 – 零知识证明。理论概念可以参考我之前的一篇小结,具体执行流程推荐阅读官方文档

有了上面的预备知识,接下来我将带大家简单剖析各个具体的隐私应用,来了解其中的加密原理。

隐私币

隐私币一般指基于比特链协议的硬分叉的区块链,一条链即一个币,也基于比特币的UTXO模型。比特链生态是没有智能合约应用概念的,我将这些功能链也视为一个个应用级的产品。

Dash

Dash采用混币系统来实现一定程度的隐私。它在比特链的基础上进行了扩展,建立了一个由主节点和矿工组成的双层网络:

  • 第一层网络中,矿工节点通过POW共识来计帐和保护网络安全;
  • 第二层网络实现混币相关的功能,主节点用于执行隐私交易、即时交易和网络管理。 节点将多方交易混合在一起再对外发送,打乱地址关系的映射。

该方法只能实现对地址关系的隐匿,甚至在参与方较少、金额数目特殊的情况下,地址关系也无所遁形。

Monero

Zcash

Zcash的隐藏原理基于单向哈希零知识证明

  • 要隐藏一个信息很简单,一开始我们就提到了各种加密方法;
  • 要隐藏一个不需要恢复的信息更简单,一个单向的哈希就可以做到。

既然我们不想让任何人查看交易细节,那我们就将这些全部做哈希处理再存储到共识节点,不就可以了?

当然共识节点也不傻,你提交一条哈希给我,我如何知道哈希所代表的内容是否准确?这时便需要零知识证明发挥作用了。另外为了防止重放攻击,还需要对证明进行签名。

具体细节推荐阅读:https://www.8btc.com/article/526391

下面我们梳理下整个Zcash的交易流程,与UTXO模型大体类似(UTXO模型的交易流程由于有P2PKHP2SH等各种类型,就不再赘述)。

首先Zcash中,UTXO模型(note)结构体如下:

  • 持有者的公钥: a_pk;
  • 数额: value,简称 v;
  • 随机数: r;
  • 随机数hash:rho,即HASH(r)
1. A -→ B 转账,多个input note -→ 多个output note(可能有剩余返还给A)
2. A解析并发布这些input note(hash)的废弃声明,共识节点在nullifier列表中验证,防止双花;
3. 同时发送新生成的output note(hash)声明;还要发送零知识证明和签名,证明A发送的这些hash声明对应的交易内容是完全正确的;
4. A将属于B的output note(detail)发送给B

注意第三步,由于链上存储的都是hash,B是不知道note细节的,但是在花费这些note时,B需要发布基于rho的废弃声明,所以A需要发送具体内容给B。

那么怎么在不安全的网络安全地发送明文内容呢?

隐私合约

Tornado Cash

Tornado是基于以太坊的混币应用,也是只能打乱地址的映射关系。

不过它有意思的地方在于利用零知识证明,实现了验证逻辑。整体流程如下:

1. 存款前生成随机数secret和nullifier,nullifier -→ nullifierHash,secret + nullifier -→ commitment,tornado note = nullifier + secret;
2. 存款时,提交commitment,没有冲突就会将commitment插入到合约地址维护的Merkle树中;
3. 取款前,输入凭证note,解析出nullifierHash和commitment,并从Merkle树中获取commitment的链路;
4. 取款时,输入取款地址,与secret、nullifier和其他证明一起生成零知识证明,以供验证

PS:Tornado的中继服务解决了支付困境问题,提款时交易费由中继者支付,同时扣除提款总额的一部分作为服务费。

Automata Network

Automata Network的定位是应用中间件,支持多链协议,它的隐私功能致力于提供一套安全可信的运行环境。

不过个人理解,像预言机一样,它提供的只是链下隐私,进行相关的证明验证,得到结果后再通知链上DAPP。

具体实现原理是通过 TEE可信执行环境Oblivious RAM 算法,创建一个本地数据无法被第三方(甚至本地进程)访问的安全空间。

TEE的具体实现通过Intel的SGX,它保证了数据隐私远程证明。保证数据隐私很好理解,远程证明是指向其他第三方提供相关远程安全证明:

  • 硬件检查:硬件制造商会有相关私钥签名,可以通过公钥进行验证;
  • 软件检查:生成软件代码哈希,进行校验

那TEE有什么作用呢?前面我们提到过完全加密很好处理,一个单向哈希即可,但难的是我们需要同时让矿工节点知道交易内容的准确性。

一种解决方案是零知识证明,但它的生成很复杂;另一种就是TEE。TEE提供了一个可信环境,除了特定的一组接口,无法通过其他方法读写数据。

通过这个特点,我们可以在其中进行任何隐私验证。如通过编写TA程序(Trusted Application),我们可以把矿工验证逻辑放到TEE中,矿工只需要知道一个验证结果。同时在不同节点远程校验,从而形成共识。

当然TEE和零知识证明也不是互斥的,我们甚至可以在TEE之上使用零知识证明。

只是对数据加密还不够,通过侧信道攻击(side channel attack)也可能被盗取敏感信息:由于数据访问模式,当频繁读写某些数据时,攻击者可以定位到数据储存位置,甚至推测出敏感信息。这时便需要 Oblivious RAM 算法来隐藏真实访问。

算法原理也很好理解,每次读写数据时,不仅仅读写所需的数据,同时读写其他数据进行混淆

隐私链

Secret Network

Secret Network是基于Cosmos的一条支持智能合约的异构链,它利用TEE实现了对隐私的支持。

一个大致流程如下:

1. 开发人员编写智能合约并部署,合约加密发送到矿工节点TEE中;
2. 节点在TEE中解密验证交易内容,提出一个包含加密输出和更新加密状态的区块;
3. 2/3 的验证者就加密输出和状态达成共识,存储合约代码到TEE中;
4. 用户向智能合约发起交易,包括加密的数据输入,流程同上;

学习 Secret Network 合约,首先要了解Rust语言,这里推荐 Rust中文圣经

学习 Secret Network 前,需要了解 CosmWasm,前者建立在后者的基础上。CosmWasm 和 Solidity 也有很多不同需要了解:https://docs.cosmwasm.com/docs/1.0/

对 Secret Network 的学习,推荐先阅读官方文档,其提供了许多学习资源。

测试网络

开发入门,推荐figment教程

里面有很多细节,如:

最后提下ERC20、ERC721规范的兼容实现:

https://build.scrt.network/dev/tutorials.html#references-for-secret-contracts

PS:这个只是对规范的兼容,没有实现支付、白名单等功能。下面这个库增加了这些功能:

https://github.com/luminaryphi/secret-random-minting-snip721-impl

Oasis Network

Oasis Network是一条支持智能合约的区块链。它采用模块化设计,提供了对隐私私有链的支持。

Oasis 由两层网络构成:共识层和ParaTime层。你可以将其理解为二层的架构设计,类似于以太坊L2的多链,在ParaTime层中执行智能合约的计算。整体架构图如下所示:

Oasis网络架构

前面提到的模块化就是指ParaTime的实现非常灵活,支持自由组合:

  • 在代码规范方面可以支持 EVM 或 WASM;
  • 在加密隐私方面可以直接裸奔,或选择TEE、零知识证明等加密;
  • 在公私链方面可以设计为有无许可系统

推荐阅读:

隐私项目