如何解决隐身地址问题
时间:2014-08-23 来源:巴比特 作者:屈爽
这篇文章的主题是隐身地址(stealth address)技术,近来由于暗黑钱包使用了该技术,所以再次被提及。 我本来不打算在bitcoinj里开发这个功能。不过,如果有人为bitcoinj专门写个隐身地址的补丁,我倒不介意把它加上。 我想说的是:隐身地址技术的设计有点问题。而且,我觉得有更好的方法可以达到相同的效果。 什么是隐身地址(Stealth addresses) 隐身地址解决了隐私问题。 假如,你用静态的比特币地址收款,虽然省事,但有可能泄露隐私。因为发款人可以在区块链(block chain)中查到该地址的所有收款记录。 一个简单的解决方法是使用BIP32 HD 钱包( 分级确定性钱包):服务器用你自己选择的数据种子不断生成新地址。由于种子藏在服务器里,这些地址之间的关系就隔离开了。但这种方法有诸多不便之处: 你得找到一个有BIP32功能的服务器。 只要你的数据种子泄露了,所有地址之间的关系就泄露了。 更大的问题是,它和BIP70(Payment Protocol)的签名方法有冲突。如果你想用地址签名,就需要服务器获取你的签名权,这降低了安全性。 为什么不直接把数据种子发给发款人,让对方生成地址呢 因为收款人需要获得发款通知,这意味着收款人必须枚举出所有可能地址。如果收款人可以枚举出所有地址,那发款人同样可以,这样对方还是可以获得你的所有收入信息。 所以,我们需要一种方法,让发款人可以在不知道私钥的情况下生成公钥,而你可以计算出对应私钥,同时,所有交易不能有相关性。这就是隐身地址(Stealth addresses)做的事情。 工作原理 PeterTodd的这篇文章详细解释了隐身地址(Stealth addresses)的机制,当然,我们也需要提一下,使用elliptic curve Diffie-Hellman 的主意是是在2011年ByteCoin提出来的。基本原理,是发款人选择一个大随机数。这个数字用一系列公式(公式中因含着数据种子)进行计算后得到新公钥,其对应的私钥只能由收款人计算出来,而且与原来的数据种子不相关。 到这步看起来还不错。不幸的是,这个方案的问题,又回到隐身地址(stealth addresses)的初衷所在。让我们忘掉这个名字,只讨论问题的关键点——如果想提取收到的钱,收款人需要一个很大的数据种子。这个种子可以公开,而且不会造成隐私泄露问题。目前隐身地址的方案,是用一个新输出把它加在每一笔交易后面。 第一个问题:隐身地址会把Block Chain撑大。 第二个问题:隐身地址的交易和别的交易看起来不一样。 这种带标签的交易发出来后,收款人首先需要找到它。通常,一个钱包是通过扫描它生成的地址来搜集收款的。但在这种情况下,地址是全新的,标签又是个随机数。因此,想找到发给你隐身地址的币需要尝试所有地址,看是否有匹配。这个模型非常糟糕。目前有些针对性的改进,但这些改进都牵扯到P2P协议的修改,社区很难接受。还有些修改,是通过简单地将收款地址分片:收款人只检测一部分收款地址。发款人通过暴力计算,把地址落在这些地址中。 第三个问题:隐身地址和手机不匹配 当然,说到“手机”我指的是任何使用CPU和电的设备。 隐身地址的问题,其实正是我们一直想摆脱的困境。地址无法扩展,因为它不能向后兼容。没有隐身地址功能的钱包软件会直接拒绝这些交易。好吧,到底隐私重要,还是付款成功重要 我想后者在现实中更重要。 第四个问题:隐身地址不向后兼容 最后,它还是继承了用地址收付款的问题: 第五个问题:你不知道是谁给你付款、为什么付款。 幸好,我们有个更好的方案,可以解决以上问题。这个方案我打算长期跟踪下去。 ECDH支付协议 我经常说起[BIP 70](https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki),因为它解决了很多问题。而且,在隐身地址这个领域上,它也能发挥作用。 一个BIP 70付款请求(PaymentRequest)消息中包含输出列表(就像地址列表)。我们可以把输出扩展成这样: message Output { optional uint64 amount = 1 [default = 0]; optional bytes script = 2; optional boolean accept_ecdh = 3; } 我们在第三个域中标出:接受elliptic curve Diffie-Hellman(ECDH)交易。老钱包不知道这个域,会直接忽略,忽略后就和传统的公钥发款一样了。这样虽然得不到隐私保护,但还是能收到钱。如果你无论如何都需要隐私不要钱,可以在协议中加入强制不兼容。 然后,我们在付款(Payment)消息中加入新的重复ecdh_nonce域。每一个nonce域(大随机数)和交易中的输出匹配: message Payment { optional bytes merchant_data = 1; repeated bytes transactions = 2; repeated Output refund_to = 3; optional string memo = 4; repeated bytes ecdh_nonces = 5; } 升级后的钱包就不使用输出了,直接使用新的派生密钥。 如果支持这种付款协议,一下就解决了前面提到的所有问题。而且,允许你加入消息后,nonce与区块链隔离,你可以直接向收款人发送交易。这就避免了扫描区块链的资源浪费,也不用对P2P协议进行大幅改进。 当然,它也带来了一个新问题。 让人对人的交易可行 大多数人可能不知道,中本聪本人认为付款(Payment)协议非常重要,他在比特币0.1(最早的比特币版本)中已经写进去了。它是通过填写收款人的IP地址实现的。实际上,比特币地址只是一个备用方案,以便你不在线时收款。 这个付款协议没有生存下来的原因之一,是早期没有商家接受比特币,所以交易都是人对人的,而很难保证对方一直在线。而且,用IP地址发款是个糟糕的想法。但是,付款协议这个想法本身非常合理。 BIP 70的方式对商户很友好。但是,由于很多功能要么依赖BIP 70要么要求商户一直在线,我们首先需要解决数据传输的问题。使用区块链存储临时数据要考虑它的昂贵性和低效性——人们已经开始抱怨传输区块链占的带宽了,再往里面塞进根本不影响一致性的数据是很愚蠢的行为。当然,如果区块链是唯一交换数据的方式,那也许是值得的,但它不是。 除了区块链,我们需要再建设一个基础设施:一个简单的存储转发网络。隐身地址的原始提案使用Bitmessage实现这一点。但Bitmessage有一些设计问题,使它不太适合做这件事。那么这个存储转发服务器需要做什么呢 接收付款请求(PaymentRequest)信息,在服务器上加载一个特定URL,使HTTP(S)GET可访问。 用该URL接受从钱包发出的付款POSTs请求,并存储它。 把这个消息返回给创建付款请求URL的钱包,然后删除该消息。 这听起来像一个电子邮件系统或即时消息系统,其实它就是这样一个系统。隐形地址的原始提案中写到:不能使用一个与比特币网络隔离的额外网络作为存储转发服务器,因为它降低了整个系统的可靠性。但实际上人们每天依赖大量这样的服务,就像依赖比特币网络一样。如果我们滥用比特币节点做存储转发服务,会导致疯狂的资源消耗。我认为我们可以用更好的工具完成这个任务。 这样的系统看起来应该是什么样子 它有点像电子邮件,人们明确地选择一个服务器和他们的钱包创建的一个账户,或者轮询新付款,或者挂一个GET响应服务。这个“账户”通过特定URL接受钱包的“POST”请求,然后输入用户名和密码后提取出一个GET。一旦付款消息下载完成,钱包负责广播交易然后给用户发出信息。人们只要选择有在线能力的服务即可,除了这些,并不需要更多的信任。因为另一个BIP70扩展,可以给消息加密,让服务器也无法得到信息内容(再次用到ECDH)。 让你亲自去调查哪个服务器有人7*24小时维护不太现实,这件事可以让计算机来做。我们把这些服务器连在一个类Tor的P2P网络上。Tor网络更中心化:它牺牲了一些去中心特性,使其工作更有效。Tor网络通过“带宽调度中心”来评估某个节点的在线时间和在线能力,这个“带宽调度中心”需要提供可信的节点能力评估值。钱包联盟也可以运行一个类似的评测服务器用来通知各钱包哪个服务器更可靠。这样钱包就可以用提供匿名账户的方式,出租它的BIP 70支付链接了。 如果浏览器可以直接解析一个随机URL并显示出简单的网页,网页上显示一个比特币地址二维码、一个“支付”按钮,就像Bitpay和Coinbase已经提供的功能一样。这就更方便了。 从长远看,钱包联名可以向存储节点提出要求,自己对其进行评估并编制调研报告,不依赖第三方的监督。这当然会消耗电池,但可以在晚上充电的时候干。然后,如果你的钱包可以连上你朋友的钱包,就可以分享这个报告了。这就成为了一个完全去中心化的网络了,而且节点之间是互相信任的。 一旦上述功能实现后,可以定义更多的BIP70扩展,比如把名字、昵称、照片和联系方式等加入到付款请求里,这将是很有用的。人们可以把钱包地址簿通过文件的形式上传到一个由社区维护的黄页服务器,这样付款时看起来就像对方在线一样。这种方式当然不需要ECDH和隐身地址,因为钱包总是可以在每笔收款后上传新的收款码,但它简化了很多事,而且避免了钱包不在线情况下可能出现的重复付款。 我刚才讲的整个基础设施可以分成不同层级,由成熟的程序员们一步步实现。如果你对这个实验项目感兴趣,联系我:[email protected] 名词释义: BIP:Bitcoin Improvement Proposal的缩写,意思是“比特币改善建议”。 BIP-32:Hierarchical Deterministic Wallets (分级确定性钱包) 参考资料: https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki http://www.8btc.com/deterministic-wallets-advantages-flaw http://sourceforge.net/p/bitcoin/mailman/message/31813471/ BIP-70:Payment Protocol 参考资料: https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki |