多重签名:未完成的革命
经过几年基础设施与技术的发展,多重签名钱包技术貌似在比特币中有了些长足进展。 Greenaddress.it 和BitGo 是业内两个比较早的竞争者,BitGo在2014年时融到1200万美元,还自称囤有价值超过1亿美元的比特币。
比特币生态系统中已然出各种多重签名钱包,开始的时候是非常受欢迎的。
多重签名钱包(下面简称‘多重签名’)的优势主要包括消费者—商家第三方担保应用,必要时允许仲裁员在开放自由的市场中保证相对安全以及无欺诈比特币交易。 另外,多重签名作为个人储蓄钱包用例中,可以使用户免受因私钥丢失或被黑带来的损失。
随着关注的焦点落于消费者保护 ,能遇见数字货币许可证(BitLicense)将为数字货币业务带来严苛限制,那么相较于该种中心化监管手段,多重签名或许为消费者权益保护提供了一种其他的可能:与其精疲力竭的保证每项业务都可信赖,不如打造一个能够最大程度地去除单点故障的体系,系统的安全性主要由数据来反映。
但是,多重签名技术也存在被误传或者过誉的风险。那么,这篇文章的要点在于定义一下“好的多重签名”和“坏的多重签名”。好的多重签名应该做到去信任,即免除人们不得不去‘信赖’其他人或机构,并推动消费者保护;而坏的多重签名仅仅是对加密经济安全性的威胁。 让我们尝试在好坏间画条清晰的线。
客户端革命
讨论多重签名前,先来分析一项广泛使用的技术,据说是可以增强安全性并降低对信任的需求:客户端网页应用。
客户端网页应用之前,比特币客户端有两种主要范式。
第一,桌面客户端( the desktop clients),可以直接下载程序。桌面客户端的好处和缺点是:自己的私钥保存在自己的电脑上,不必依赖第三方存储自己的资产;但是易用性就差点了,需要用户专门去下载应用。
第二,服务器端在线钱包(the server-side web wallets),就是有个第三方替你保管比特币,给你一个账号能够各种转入和转出,好比谷歌和脸书账号,不用下载任何软件。在线钱包的易用性不错,但是要求用户对第三方的信任。
客户端网页应用( Client-side web apps )是美好的第三种解决方案:依然是通过网页应用登陆网站,但是不用下载相应的软件,使用网络浏览器内置Javascript编写的客户端完成私钥的存储和变更。可以说是综合了上面两种客户端各自的优势:既有服务器钱包的便捷性,也有桌面端的私密性。
我们来评价一下这种范式的优点。 客户端Javascript当然不乏批评者;(Matasano专门写了篇名为“Javascript Cryptography Considered Harmful”的批评文章)。 文中的观点有些极端,完全否认了浏览器客户端加密的优势,但确实也有合理的地方,比方说,若下载了某浏览器Javascript,说明还是存在信任的情形的,至少是完全信任Javascript的来源。这也说明什么呢,假设http://blockchain.info或某个变节了的http://blockchain.info员工愿意(或者被胁迫),就可以向用户A发送能套取A私钥的代码然后用A的私钥签发交易直接把账户里的资金卷了,留下身后一脸懵的A。
试问,各种情形下究竟有多深厚的信任?那么,我们看一看,想要成功实施攻击,都是什么门槛。
原始桌面客户端:代码服务商(提供者),或者黑进代码提供者系统的攻击者,需要在Github上的客户端版本库里提交包含后门的补丁,而用户需要在有人扫描源代码并发现这个后门(补丁)之前,下载客户端,才会被黑。
普通人使用的桌面客户端:代码提供者,或者黑进代码提供者系统的攻击者,需要编写并发布包含后门的客户端版本,而用户要在服务商检测到这个漏洞之前下载。(多数情况下,很难通过反编译二进制客户端发现后门,因此只能是服务商内部才能会检测到漏洞。)
客户端浏览器网页应用( Client-side browser webapp):攻击者需要在内容发布网络中快速插入包含后门的客户端版本,自恶意版本插入到下线期间登录的用户最有可能受到威胁。
服务器端浏览器网页应用( Server-side browser webapp ):攻击者仅需访问网站冷钱包,一旦访问成功,任何用户都将受到威胁。
以上四种,按照安全级别排序,越往下安全性越低,需要投入的信任也越多。 短期和长期的攻击者之间有个明显的区别:所以说是公司(服务商)比较邪恶?还是那些利用漏洞钻进服务器的几分钟或几小时直至被发现的捣蛋鬼比较可恶?对付长期攻击者,或许只有从开源社区下载稳定的版本才靠谱,而对付短期攻击者,二进制(普通人使用的桌面客户端)的桌面应用就够用了,连客户端浏览器网页应用也能防止一小撮用户悲剧。
一般来说,桌面端和浏览器端有着根本的区别:前两个,如果攻击者短期侵入,安全设置正确的前提下,不足为害,因为问题能很快解决。而在后两种情况下,短期侵入也是有害的。 只能说客户端浏览器应用的安全性比服务器钱包高了一点点而已。
问题怎么解决呢?
最简单的办法是将客户端的网页应用改成浏览器扩展;从安全角度看,浏览器扩展相当于,比方说在Java或者Python交互环境中运行的,桌面应用。 然而,这样做需要额外的步骤,就是用户除了单纯的信任服务器,还要下载一个浏览器扩展。
注意,以上并非针对客户端浏览器Javascript;想表明的是,客户端浏览器Javascript并不比服务器钱包的方式更安全或者更去信任。
应该编写客户端浏览器Javascript加密货币应用的理由还有便捷性。作为开发着来说,浏览器能处理越多的事情越好,这样就不用花很多精力在基础设施建设上了。
也正是因为这个原因, ether sale webapp使用的就是上客户端Javascript(开发方便且稳健对抗拒绝服务攻击)。 当然,使用这个App的时候,用户是相信以太坊的,但是没关系,反正以太坊本身就是供搭建的平台。
熔合的多重签名钱包
有关客户端安全性的讨论很重要,因为源代码自身的安全性时常被忽略。 尽管比特币加密协议理论上讲是去信任的,但几乎没有人可以独立检验全部代码。因此,除了程序协议的原始开发者,几乎每个人都要在一定程度上表现出信任。
多重签名中,我们的目标是完全的去信任。一般来说,有两种多重签名实现的途径。
第一种叫2-of-2扩展版。2-of-2的概念比较简单,用户掌握一把私钥,(脑钱包、浏览器或客户端随机生成的加密私钥)。服务器掌握另一把密钥。 用户想要交易时,在电脑上登陆钱包,然后用自己的私钥签署一笔由自己的地址发送的交易,然后交易送达服务器,由服务器做些反欺诈检验,比方说,向用户的手机发送验证码,要求用户输入该验证码。验证成功,则服务器签署交易并发送。
但是这个方法本身是十分脆弱的。 一旦用户电脑被攻击,或者忘记密码,将无法登录钱包,这个时候服务器是一点忙都不上。 再或者,运行服务器的公司出了什么意外,或故障,再或者跑路了,用户就悲剧了。
2-of-2扩展版就很好地解决了这种问题。 是这样的,客户端每次发起一笔新交易,实际上产生两笔交易:第一笔是想要转出的金额,第二笔则是在第一笔交易完成后,将其余的资金转移到本人的其他备用地址。 服务器会签署全部两笔交易,但只有第一笔交易是公开的,第二笔交易将返还给用户,这样即便服务器消失,用户依然有办法恢复自己的资金。 注意这是2-of-2地址,因此服务器无法在不经用户同意的情况下撤销用户的交易。 还应该注意的一点是,服务器应该是首先签署交易的,否则就有可能出现服务器恶意的只签署第一笔交易但不签署第二笔的可能,然后跑路,留下身后风中凌乱的用户。
第二种是简单的2-of-3。有三把私钥:用户私钥、服务器私钥,还有一把用户以安全的离线方式保存的私钥。 跟上面一样,用户签署交易,服务器向用户手机发送验证码,然后用户在电脑上输入验证码,然后服务器签署交易;流程没变。但是,如果用户遗失密码,可以用备份私钥和服务器私钥发送交易到一个新钱包;如果用户或服务器被攻击,攻击者也仅仅是获得了三把私钥中的一把;如果服务器有意作恶或者跑路,掌握的也是三把私钥中的一把,而用户掌握了三把私钥中的两把。与2-of-2的逻辑类似,丢失私钥或服务器消失的情况下,用户可以申请紧急交易。 能看出,不管是2-of-2还是2-of-3,套路大体都差不多,不同的地方是2-of-3着重强调了单点故障的应对。
之前有个比较火的多重签名钱包是BitGo,多数情况下作为客户端Javascript网页应用出现。这里不是特意针对BitGo,只是在分析具体情况。 如果攻击者控制了BitGo的服务器,就能向用户推送错误的网页应用。再或者,还能控制服务器的第二重签名,因此,本身就是所谓的单点故障。
当然了,人们是这样认为的:(1)BitGo值得信任,因此不太可能监守自盗,(2)多重签名也意味着攻击者必须攻击服务商和用户双方才能成功。
但是,这并没有绕开单点故障这个软肋。 中心化的服务器端钱包可以达到相同的安全水平,还不需要用户额外的增加一重签名或者使用冷钱包备份。 因此,可以将这种客户端浏览器多重签名钱包视为是加密经济安全性的威胁。也不是说BitGo不安全,只是说这种所谓的“多重签名”钱包并没有人们想象中的那么安全。
为什么说浏览器Javascript与多重签名组合在一起就出问题了?是这样的,浏览器Javascript多重签名钱包的服务商(与很多桌面应用的服务商一样),从一开始就想打造不受单点故障影响的协议,但是他们在协议中同时扮演着两个角色:客户端和服务器,实践中这也牺牲了本想到达的优势。是这样,无论以如何形式下载软件,除非有时间检查每一行代码,要不然就得相信软件服务商。 乍看起来,这个问题貌似无法避免,但解决办法其实依旧来源于多重签名。
未熔合的多重签名
多重签名的正确操可以参见CryptoCorp。 他的手段是什么呢?首先它不是Paypal模式(几乎所有前加密时代业务模式)。 Paypal模式中将界面与安全提供者打包在一起。 而CryptoCorp则是把界面单独开来,然后把安全提供者功能作为自己唯一的核心。也就是说,CryptoCorp将大量资源用来专门开发并改进自己的签名预言机服务器的算法和高级功能。然后,兼容界面就交由其他的钱包服务商。
当然,CryptoCorp的出色之处还在于用来甄别不正当交易的先进算法。花三刀买杯咖啡这种事,CryptoCorp应该懒得验证;花500刀买个笔记本电脑,或许会稍微检查一下;而花50000刀买辆车,就准备好接受KYC认证般的检验吧。 除非收款地址被认定属于老牌的BitPremier,这种情况下发送交易回相对顺利,因为一旦发生错误总是可以要求退款,但是,若接收地址与黑客有所关联,那么即使是3刀的交易也会请求验证。
所以,CryptoCorp好在整个预言机的搭建与整个软件的维持是完全分开的。 使用CryptoCorp,即使用户的软件完全被攻击者控制,依然是相对安全的。 用户可以使用独立的工具验证看到的地址是是否合法。 客户端不能单方发送交易,若客户端试图发起类似改变交易输出或者数额的攻击,会为预言机所察觉。 因此,避免了单点故障,并实现加密货币去信任的愿景。