E30·随机的含义 —— Coldcard 签名器致命漏洞暴露之后
曾汨: 听众朋友们大家好,欢迎收听《亿聪哲史》第 30 期,我是主播曾汨。
阿剑: 我是主播阿剑。
曾汨: 7 月 30 号,陆续有多名 Coldcard 的用户发现自己存放多年的比特币在没有操作钱包,也没有泄露助记词的情况下,突然被人转走。随后,Coldcard 的制造商 Coinkite 发布安全公告,确认部分旧版本的固件在生成助记词的时候,存在一个严重的随机数漏洞。这个问题最早在 2021 年 3 月进入 MK2 和 MK3 的固件,后面也影响到了 MK4、MK5 和 Q 等型号。正常情况下,Coldcard 在创建新钱包的时候,应该调用设备里面的硬件随机数发生器,较新的型号还会加入安全芯片提供的随机输入,以生成具有足够随机性的助记词。而在受影响的固件当中,程序没有真正调用预期的硬件随机数发生器,最终使用了软件库里面的一个简单的伪随机数发生器,这样生成的助记词可能被攻击者推测和枚举。正常的助记词具有大概 128 位的安全强度,也就是 2 的 128 次方可能性。但根据 Coldcard 官方的初步估算,受影响的 MK2 和 MK3 有效的搜索空间可能只剩下不到 40 位,而像 MK4、MK5 和 Q 的型号也只有大约 72 位。这意味着,攻击者可以在自己的计算机上批量枚举可能的助记词,再和公开的比特币地址进行比较。一旦找到匹配的结果,就能够转走对应的资金。整个过程不需要拿到用户的设备,也不需要让钱包连接互联网。截至我们录制这期播客节目的时候,第三方的研究机构 Galaxy Research 报告称,至少有 1596 枚比特币在多轮攻击中被盗,涉及大概 7300 个地址,价值上亿美金。还有一轮一次攻击没有被统计进来,如果得到确认的话,损失可能上升到大概 2055 枚比特币。
这件事情给比特币社区带来了很大的冲击,也让我们开始思考,硬件钱包究竟能够提供怎样的安全保障。今天这期播客,我们并不会在这期播客里面给出关于使用了故障的 Coldcard 钱包的用户,你应该怎么样迁移自己的资产。相关的教程已经有很多,我们也会放在节目的 shownotes 里面。如果你是这一次故障受影响的用户,在听到这里的时候,如果你还没有迁移自己的资产,你现在要做的最关键的事情是停下手中的播客,立马去做这样一件事情。今天这期播客我们邀请到一位安全领域的嘉宾,也是我们《亿聪哲史》的老朋友姚翔老师。我们想来一起复盘一下这次的 Coldcard 的事件。那么首先,姚老师先和我们的听众朋友们打个招呼吧。
姚翔: 大家好,我是姚翔。今天没有很高兴来到这里,因为这个事情比较沉重。我想和大家讨论这件事情,也是为将来的密码学和密码货币设施的发展提供一些自己的观点。谢谢。
曾汨: 好的,欢迎姚老师。那首先其实刚刚我在开场里面提到了这一次事件的根源,是因为 Coldcard 在生成助记词的时候。它的随机数不够随机,但这个故障我相信对于很多听众来说是比较陌生的。那么想先请问一下姚老师,软件钱包和硬件签名器中的随机数生成器这个故障,和我们一般理解的功能性故障,比如说钱包死机,软件崩溃这些故障,它有什么样的区别?为什么这种故障会造成如此严重,甚至无法挽回的后果?
姚翔: 好的好的。首先我想特指这个硬件签名器的时候,就是这个硬件签名器它到底执行了什么样的功能。那么从这次事件来看,我们结合这个事件来说,它第一部分的功能就是它不一定是必须的,但是是可选的,去帮助用户生成这个私钥,或者说是可以推导出私钥的这个种子的数据。第二部分才是他可以对比特币网络上,或者说包括其他区块链的网络上的交易数据进行签名。所以其实它主要是这两个功能。那这次的出问题它其实是在第一个部分。那为什么这个随机数在这里面这么重要?其实很多我沟通过的朋友啊,包括一些感兴趣的人吧,他们对比特币是怎么运作的有一些误解。实际上比特币它的安全性本身和谁能转移哪一笔钱,这是两件事情。那么在这个账本上怎么去保证这个账本不被修改?是有一套密码学机制,但是在谁可以去花费某一个交易的时候,这是另外一个机制。这个机制它利用了密码学里的这个非对称的密码算法,也就是说不一定啊,不一定啊,但是大部分的这个比特币上的 UTXO 是通过这种方式来管理的。那么也就是说你需要有一个私钥,然后呢这个区块链上以某种方式记载了相对应的公钥值,那么这个账本就会去检查,通过数字签名的方式来检查交易是否是合法的,重点就是他只去检查这个签名,他不去检查任何其他的东西,甚至极端情况下,如果用户没有就是私钥,他被攻击者诱骗签了一个假的交易,那么攻击者在不拿到私钥的情况下,也可以通过直接广播这笔交易来转移用户的资产。当然这种情况下也许用户还有机会,是因为他可以再去花更高的费用来想办法让这笔交易不被纳入。所以我们就知道这个私钥就意味着对资产的控制权。那私钥是怎么来的呢?它其实它就是一个随机数。
它当然是一个秘密,但这个秘密和我们平常理解的这些秘密不一样。我们平常理解的秘密,我把这个秘密我给它加了一些特性啊,然后这些特性是我觉得和我们的日常经验有距离的那个部分。首先它是一个不易更换的秘密。这个原因是当我们拥有了一个比特币的钱包之后,我们会在里面拥有一些资产。大部分人他就会使用这个钱包来管理他的资产。这个秘密不太会经常更新。经常的更新意味着你要做非常多额外的工作。我举个例子,你有很多个钱包,然后你可能今天从 A 钱包转到 B 钱包,后天再从 B 钱包转到 C 钱包,并且你过去的所有的这些钱包就不再使用。而且同时它们还得是不同的种子密钥来生成的。这听上去并不是一个对普通人来说可以实现的东西,所以它不易更换。可以无限次去验证的秘密。它不是一个有限次可以验证的秘密。这个我一会儿去讲。然后同时它这个验证可以是没有痕迹的。就是你并不知道有没有人在世界的某个角落来验证这个秘密。我们把比特币账本看成是一个访问授权控制的系统。我们就会发现这个三个特性是非常非常非常独特的。比如说,由于它不易更换,那么这个秘密在很长一段时间内它其实是确定的。那么我作为攻击者,我可以先去不断地搜集,然后来一起攻击。这是为什么呢?是因为一旦我发起攻击,就暴露了可能某种像现在这次事件出现的缺陷。但是这个事件它持续五年时间,其实我们并不能确定,攻击者是什么时候开始攻击的。这是因为它由于秘密是确定的,同时由于它没有痕迹,那这个攻击的过程是完全不被知晓,匿名。在法律和现实的这个意义上,攻击者是很难被发现了,他只能是可能通过其他的东西去找到它,至少他有足够的手段来逃避这个被追踪。
第三呢,由于这个你可以无限次的去验证,所以这个秘密它就不能太简单。这个道理非常简单。我说个无限次验证的一个场景,就是你在马路上捡到了一个别人的密码箱,这个密码箱锁是三位,然后你不需要任何复杂的知识,你只要有耐心,大概一个小时左右你就可以把这个箱子打开,因为它的这个密码的组合可能性就是 1000 种,你不需要有任何复杂的知识。你只要不停地去转动它,然后它就一定可以打开。但是我们想,如果这个密码箱的数字盘是 1 万位呢?是 10 万位呢?在这个情况下,你如果没有知识,你就不可能有办法保证你可以把这个箱子打开。那这时候我们就需要一些其他的东西。所以这个无限次的验证,这个特性其实是非常非常关键的。那我们再想一个场景。比如说任何需要二次验证的场景,你登录任何网站,它有可能会要你用短信或者邮件的验证码,或者是有类似像谷歌的这个认证器,它基于一些密码学的手段,它既有痕迹,它也有次数的限制。否则的话,我可以想办法去登录一个人的账户,比如说我知道一个我想攻击的人的账号,我就用手机验证登录,对吧?那不就是一个六位数字吗?那我总有一天可以试出来,有的甚至只有四位数字,对吧?但是因为它会有次数的限制。它不让你去多次的尝试。这个是因为它有一个中心化的一个机构,所以它会让这样的攻击的行为的风险,它并不能因为攻击者有足够的能力,比如说我现在有一个程序,可以无限次的去尝试这个短信验证码或者是这个验证器的验证码,但是因为这个中心的服务拒绝你,比如说三次以上的试验,这个说到一个更极端的情况,就是比如说我捡到一个人的硬件钱包,当然这个可能性很小,大概率可能是有些人的钱包被偷了,或者是被抢了。那攻击者他拿到这个,
他能怎么做呢?他是没有痕迹的对吧?假设真的就是捡到了,那没有人知道我捡到了一个在家里,我就在家里偷偷试。但是因为他有次数的限制,比如说你尝试三次或者四次之后,这个设备里的东西就全部被删除了。基于这些。我们在大部分场景下对安全的理解,就是它的条件都不是像随机数之于比特币这么重要,以及这么重要,就导致我们对这个随机数生成器里面这个故障所要承担的这个后果就变得更大。至于这个事件发生的本质,有很多的分析文章,就是因为怎么怎么样,它的工程上出现了一些问题,我也不想再详细叙述这个过程,但是总之它导致了一个结果,就是就回到刚才那个箱子密码锁的那个事件,就是你可能以为你买了一个给箱子上锁的那个锁,然后你以为这个锁可能有一万个数字,然后在这个场景下可能它就只有几个数字,由于不管什么原因,大部分的数字就失效了。所以对攻击者来说,也不能说不费吹灰之力,但是基本上是在一个很容易的场景下就把这个箱子给攻开了。这个就是这个事件,它为什么这么要紧,随机数这么要紧。而一般的这种功能性的故障,它不涉及安全。回到曾老师的问题,功能性的故障可能就是它不可用。或者是它的行为和预期不一致,比如说这个机器打不开,或者是它签名的时候签的数据出现了错误,这些它并不会带来这种安全性上的攻击的可能性。我大概说的有点多,但我还是想强调就是这三个特性在我们生活中任何的常用经验里,同时具备这三个特性,我认为这是唯一的一个场景。
曾汨: 那其实总结起来,私钥它是一种很特殊的东西,而我们以往的这些经验是完全没有办法套用到私钥的这套安全体系上来的。对吧?
姚翔: 是的,我是这么认为,以及在之前密码学面对的那个外部环境和引入密码货币引入比特币之后的这个密码学所面临的外部环境发生了巨大的变化。甚至我认为很多密码从业人员也没有做好这个准备。
阿剑: 在姚老师的那个比喻当中,我们把它理解成一个密码箱。这个密码箱它本身有很多很多位,所以如果有一个人拿到那个箱子,他会需要尝试很多很多次数。比特币的种子词或者它的私钥的特殊性在于,实际上大家不需要拿到这个密码箱。它只要在虚空当中不断地尝试生成随机数,就可以尝试跟你生成的那个产生碰撞。或者说它有意识地通过一些可能被人们使用来生成随机数的这个过程,自己向同样的过程注入数据来暴力地搜索它,只要它碰撞到了跟你相同的。或者说他搜索出了跟你相同的那个随机数,他就能打开你的箱子,拿走你的比特币,因为那个箱子它存在于整个互联网上,别人不需要拿到这个箱子。这才是这次的事件非常可怕的地方。
姚翔: 对,谢谢阿剑的补充。就是数字世界里面,很多人也确实觉得这个硬件在我手上,别人是怎么可以拿走的?其实你只要想一想为什么你要备份这个助记词就可以了,而不是说我有这个硬件在手上,它就是安全的。
曾汨: 那么在过去的密码学产品,软件钱包和硬件设备当中是否发生过类似的随机数事件?这些事件与本次的 Coldcard 的问题有哪些相似或者不同?
姚翔: 在做节目之前,我去做了一些调研。我想从一个更大的范围,不止在密码货币这个领域,我说一些我印象中印象比较深的事件。它也会对我们接下来讨论的东西有一些输入和启发吧。第一个是当时索尼的游戏机。这是 PS2 还是 PS3?他们在使用这个密码学签名的时候错误地使用了。我记得他应该是对这个签名当中所需要的一个随机数进行了复用。这个复用就会导致这个可以通过搜集两个签名就可以复原私钥。这个是一个很典型的工程人员对密码学不理解。所导致的这个造成密码学安全问题的一个事件。然后呢,还有一个我印象中比较深的一个事件,就是其实有一个一直在以太坊上做对私钥的高位全为 0 的这种地址进行持续的扫描。因为很多软件它由于各种故障嘛,导致这个私钥的 16 进制被截断,实际上它的有效位数只有 32 位。那么前面是全零,然后其实一直有对这样的地址的跟踪。这是一个叫 Ethercombing 的公司它的发现,然后有专门的公司在做这样的攻击,这是我记得的第二个事件。刚才第一个说的是这个 nonce 的复用,第二个说的是这个有种种原因导致私钥的长度被截断。我去做了一些搜索,其实这些事件还是蛮多的,但是我更多是想从对我们怎么来设计这个硬件产品,或者说怎么来理解一个东西,怎样才是安全的角度来谈论这个事情。所以我也就不再提更多的案例了,因为过去的这些经历都应该成为一种经验和教训,而不是成为一个只是被反复提起的一个事件。
阿剑: 其实在密码货币行业,因为软件实现或硬件实现当中的随机数发生器出现故障,导致所生成的种子词本身有缺陷,可能被碰撞或暴力搜索。这个事情实际上发生过相当多。我们提一个在比特币的领域比较著名的例子吧。这个事情其实在《亿聪哲史》之前的播客当中也出现过,那就是在 Mastering Bitcoin,精通比特币这一本书,就这本非常著名的相当于是教科书一般的书当中,他在讲解私钥的生成的时候使用了一个库作为他的这个案例代码,但是这个库相关的函数,里面他其实写清楚说我这个不应该用于生产环境,但许多开发人员没有仔细去看库当中的注释,没有理会这种安全警告,他们只是看 Mastering Bitcoin,然后就把它用到了生产环境当中。这个事情的影响非常广泛。有一种意见认为在过去几年发生的陈志案当中,陈志本人正是使用了这个叫 Libbitcoin 这个库,或者说这个网站来生成他自己的种子词。然后用在了其他服务当中,导致他所保存的比特币私钥被攻破,然后资金直接被转走。当然陈志只是这个故障当中的一个非常著名的受害者,但是实际上这个漏洞的受害者还挺多的。这个也是比特币领域里面发生过很大的一个因为随机数故障而造成的一个事故了。
曾汨: 好,那我们回到 Coldcard 这次的事件。从工程的角度来看,姚老师你觉得这次 Coldcard 签名器发现的漏洞是一种很容易避免的漏洞吗?你认为最关键的失误发生在哪一个环节?
姚翔: 本人可能是对安全方面的理解就思考的更多一些吧。其实我不是一个非常懂软件工程的人。但是在这个事件之后我也去反复想这件事。我假设在听的这个各位听众都对本次事件有一个基本的理解。我不再去做详细的复述。但是我用一个简单化的方式来描述这件事情,就是这个团队他写了一段没有问题的,或者说是符合预期的随机数生成的代码。但是他在调用代码的时候,他没有正确的调用这个代码。同时他因为他的代码库里有别的软件提供的函数,然后这个函数实现了一个比较基础的或者说随机性不够的代码。由于他在软件工程中的错误,导致错误的代码被引用了。这个就是这个事件我做了一个非常粗暴的抽象化的一个解释。那我不从那个软件工程角度出发。我只想说就从这个简单的事情上来看它是不是容易避免的漏洞。我想这个就要看在谁的角度来说。我先给这个不容易发现这个角度来来给一些理由。第一个理由是随机数的好坏或者说它是不是符合预期,这是极难检测的。就是其实你没有办法知道它是不是一个好的随机数,它都是随机的。你怎么去检测呢?数学上是有一些方法来检测一些数据是不是够随机。但是他没有办法知道他所在的密钥空间是不是足够大。我这个是我说错了,希望有密码学专业的朋友可以纠正我。但总之来说,很难站在一个软件的开发者角度去从输入和输出的这个结果来判断这个随机数是不是好的。然后第二点是为什么不容易发现呢?是因为就是大家会有一种心态,这么多年都没有出事了,如果他有事情他早就出了,以及他的代码是开源的,我假设大家都认真的看过了,这里面有一种很强的搭便车的心态。就是这么多人都喜欢,然后以至于可能我作为一个用户,或者甚至我是个专业人员,
我也不太会再产生对这段内容进行自我查验的一个心态了。就大家都觉得它是对的,那么也不会再有人去质疑它。所以这是我能想到的两个辩护的角度。那从反面去讲这个事情,就是说为这种应该被发现找理由,那我觉得也很多。比如说你有没有用正确的工程规范,比如在硬件开发里其实是有一些规范的,这个硬件的规范叫 MISRA C,这是我查的,它对这个编译的规则,对于你用宏的定义,我不说那么多细节,就是它鼓励你怎么去写代码,怎么样去显式的表达,就是要让错误显式的出来,而不是静默的去降级,这在硬件开发里是有一套规则的。其实你说。我就没有再要求这个团队做更多的事情,只是让你按照一种更好的方式来开发嵌入式的产品。这是我想到的第一个理由。第二个理由就是你但凡去找一个公司做代码的审计,他也不会对这个很容易发现的代码层面的东西忽略,因为这是成为他的工作。他的工作就是对这些领域进行检查。那第三点我还想补充一个点,就是鉴于密码学在密码货币里的这种主导性的重要性。现在的这些软件开发的管理和编程语言的对待,相关的密码学原语的处理。我认为还没有形成一个足够的尊重。在这个事件之后,你比如说让我能想的这件事情是什么呢?就是我要对所有影响生成随机数的这个区域进行一个公开的披露,就是我要说我的熵是怎么选择的,我的随机数是怎么生成的,我的哪行代码起到了什么作用,这是一。第二,我在整个的这个开源项目里面对相关部分的任何修改,都必须有一个很严格的检查。然后这个是要在这个编译过程当中可以通过这个门禁系统来进行实现,也可以通过这个 code owner 的制度,就是要求对相关敏感代码的这个更新必须要有安全人员来确认,
而不仅仅是开发人员就可以自行决定。然后再比如说就是我个人觉得需要有一些这种 bug bounty 的机制。来鼓励白帽子早期的介入到一个项目的发展当中。所以我觉得从正从反方面我都能找到理由,但是这个其实可能并不重要。我想说的,更重要的是,前面那些我为这个漏洞不容易发现所辩护的理由应该是我们应该想办法去避免的。而后面我说更加严苛的这些理由,我觉得是今后无论是我们作为使用者,还是作为开发者,都应该去多想一想有没有一些更好的方式来提高这个代码的安全性和健康性。
曾汨: 通过 Coldcard 这一次事件,其实可以看到整个行业层面存在很多问题,比如说像对于生成私钥管理这种最敏感的操作,每一个硬件钱包,每一个软件钱包都有自己的实现方式,自己的流程。所以其实姚老师刚刚提到的是说,我们可以怎么样去建立一套共同的行业规范,来推动很多事情更规范的发展。是这样吗?
姚翔: 对,我想说是每一次安全事件,这些事件历史上一次次在发生,然后每一次之后大家都应该从中学习到一些什么东西。我举个例子,比如说刚才我提到的这个索尼的游戏机的 nonce,就是签名时所需要生成的一个随机数的重用事件。在这个事件之后,大家就发现,哦,原来签名的时候随机数一样会导致这个问题呀。但是是什么呢?是我怎么能保证这些工程员能够很好地执行这个?他们又不懂密码学,所以我们就做一个什么呢?我们就做一个叫确定性的随机数生成的方案,这就是 RFC 6979,它就是让你从数学上保证这个随机数它不是那么随机,但是至少你不会重复,这是很重要的事情,以及再往下走一步就是干脆你也不要能选随机数了,就是我们走到了新的密码算法,比如 Ed25519,就是我是相较于这个 ECDSA,尤其是比特币这条曲线来说的,就你的随机数就是确定的,你没有机会让你工程员做这种实现,这就是更加防呆的密码学的设计。这是一个我觉得很重要的点。那么包括比如说去进行随机数的生成。那这次事件它背后其实有一个原因是他们在 2021 年时候,他们自己重写了这个库。这里面当然有一些软件许可证方面的一些争议啊,就是他们不太希望自己的许可证被上游的代码所传染。他们想做一个商用的产品,他不希望他们的代码被传染之后被其他项目方所使用。我觉得这其实就是在回避大家共同创造的一些东西。我对此没有批评,但是它导致了这个后果,我们今天可以回头看,它当时的那个选择有它的道理,但是它在安全上没有投入足够多的资源。所以我想基于这个事件之后,大家除了去和 Coldcard 的这个公司和它的这个产品之间有一个理解,或者说甚至对受害者来说其实里面可能还存在一些博弈,
就是即使我们知道币可能是没有办法转回的,那至少这个产品我是不是可以退款了,其实还存在一些这个方面的问题。但我想说我并不是站在一个旁观者的角度。我想说大家可能是从这里面去中间整理出一些共同的东西。因为我知道这个事件在发生之后一定有无数的人在问自己的 AI,让他去看其他的硬件钱包的代码库有没有问题。有的人是出于。防御的善意的心态,有的人可能就是出于攻击者的心态,我觉得这都很好。但是如果是这些都是很分散的努力,我觉得这些事一定还会再重来的。那我想的是说如果有一个大家能形成不一定是那种那么正式的东西,但是至少是一些原则性的东西,比如说嵌入式开发的时候应该遵循哪些规范?那我在作为一个用户的时候去审视你的这个代码的时候,我会有一些依据。比如说虽然他的生成大家都有自己的实现,那我是不是至少有某种去对你的实现去进行一个验证,或者说进行评估的一种方法。这个在行业里目前来说是比较缺失的。这也是我和一开始说的。密码货币的出现让密码学所面临的外部环境出现了很大的变化。以前就只有 PRNG,就是伪随机数生成器,现在就必须是 CSPRNG,它必须是密码学安全的伪随机数生成器,这个其实特指的就是密码货币的领域,它其实不面向其他的行业,而整个软件业的更新我觉得还是远远不够的,这个是我作为从业者这个角度的一个想法,这是从大面上说的,然后从这个细节上来说,我就想特别想谈一谈这个随机数的这个生成,为什么它是一个很难搞的事情?我们知道什么东西叫真正的随机。我们上学的时候去学这个随机统计学吧。有的理工科的听众可能也学过随机过程,或者是这个相关的一些数学统计学相关的专业的听众,对这些都应该很熟悉。
我们把什么叫随机,我们不会说明天的天气是随机的,虽然天气预报可能不准,但是在我们的这个语境里面,它就不是一个随机的事件。明天的天气和今天的天气一定是有关系的。但是在密码学上,我们希望那个随机它很像是最常见的这个比喻,就是抛硬币,那是 0 还是 1?但是其实你细化到每一次那个抛硬币的那个过程,去计算那个初始的角度和速度,其实大概率是能算出来的。如果我们拥有一切的参数,虽然在这个角度上它不是,但是我们是从那个长期来看那个结果上,它满足了某种规律。就是每一次它出现正面和反面的可能性是差不多的。下一次和上一次之间也没有关系。我这也不是很精确的描述,但是这个随机性一旦到了软件的层面就出现了问题,就是我得有一个参考系统,对吧?这个参考系统是什么?我是一个软件,大家就在想,我现在让你去想一个随机数,我说曾老师你告诉我一个随机数,曾老师脑子里去转了一个数告诉我,他说这就是我想的随机数,我说那你怎么告诉我它是随机的呢?我们就知道这一定不是一个好的方式,所以我们是需要依赖一些足够具有统计意义上特性,但是又完全不可预测的东西。那么在具体的这个软件这个层面或者说硬件的签名器这个层面,它有一个芯片,我们都知道芯片的一开始那个初始化的状态都是设计好的。然后他所有的这些代码,所有的一开始的这些参数,在他第一次启动的时候,这些东西都是设计好的。也就是说,在一开始,他的所有的条件都是一致的。他可以用不同的算法去把这些已知条件进行无限次的变换,但是他仍然是确定的。所以这个时候他就必须要去引入一个我们叫熵源,就是需要去提供这个混乱的东西。这个混乱可以是任何东西。
仅仅利用这个硬件里面本身的那个东西,我只能说是比较难的。现在一般的方法它会根据这个系统当前的状态,然后时间,时间也是个很重要的要素,就是比如说现在的,我有点忘记了现在的操作系统的这个软件函数怎么实现的,但是大概率就是跟你的这台电脑现在的这个空间,然后这个时间是有关系的。但这些东西它就是一个很混乱的状态,它不代表它一定不确定。所以硬件签名器它产生这个熵值,像这次的事件它是一个工程上的一个问题。他等于从一开始他就决定了就是在代码层面他就一定会出这样的事情,但也有一些意外发生,比如说像历史上也有事件,就是他的设备在启动的时候,会通过某些代码产生混乱度。但是他的熵在产生混乱开机之前就已经产生了,就是代码出现了问题,这个就可能叫熵池没有就绪。还有一些是出于某种原因被截断,导致这个随机数出现了问题,把一个原来可能比如说 128 位的,但它最后只输出了有效的 32 位。还有一些特别小众的场景,这个是我之前在工作中也遇到过的,是什么呢?在一个很小的概率下,这个就说到了这个软件行业,它还没有快速地适应外部环境的变化。它会把高位的这个,比如说你产生了一个私钥,它的第一个字节全是零,就是说它有前八位的零。那么在这个情况下,它会把这一位省略掉,它不会补足到那里面。然后如果你代码写得不够好的话,那可能我不知道没有技术背景的听众能理解,就是这个整个数会往右移一位,往左移一位,就会导致这个需要在一个极小的概率空间下会出错,而且这个事件在平常的测试中,去触发的概率不大,因为它正好是一个二百五十六分之一。他没有想到不会发生,但是它也不是一个你测试中就一定能测出来的东西。这是我之前工作经验中真实的故事。
这个原因是因为在实现这个相关的密码学函数的时候,他没有使用密码学相关的库。就是导致这个系统把私钥这样一个东西和对待一个普通的数没有加区分。这些都是一些非常细节的东西。当然还有一个很有意思的,就是有些人就觉得自己可以写密码学算法,然后就自己魔改了一些东西。这个历史上也是有发生的,大家一查也都可以查到。对业界公认的一些密码学算法不信任,就自己实现了这些东西,这都是造成一些事件的原因吧。回过头来说,生成随机源这件事,反正它就是很难。我的想法是说,它没有一个什么最佳的实践。重要的是大家要怎么去理解随机源的这个重要性。这样在设计产品的时候,才会给开发者和用户都有一定的心理空间去重视这件事情。而不是简单的让用户觉得好用就可以。
曾汨: 我觉得可以延展出一些比较有意思的防御随机数生成的方式。因为姚老师刚刚提到说,我们很难验证一个东西,就是你给我一个随机数,我很难验证它的随机空间到底有多大,对吧?然后我想到一个很简单的例子就是,扔硬币,你是完完全全可以验证它的随机性空间的。因为我扔一次,就是 2 的 1 次方。那我扔 10 次,就是 2 的 10 次方。我扔个 128 次,就是有 2 的 128 次方。那这个随机性空间是我们可以得到计算出来的。
姚翔: 但是在实际操作当中,谁来抛这件事情,其实也是很难对简单的当做一个不可忽略的外部因素的。因为你如果不对这个硬币本身有一个要求,大部分其实是有某种习惯,甚至有专门抛硬币的那个实验,就是他们去做了很多次,正反也不是 50%,当然这是另外一件事情,但是我想说你说的这个密钥空间这个本身是对的,但是就二分之一这一件事情以及每次完全独立,这可能也是稍微有一点点偏差,但是我觉得可以接受。包括扔骰子,其实你知道那些赌博的人嘛,出唠钱,他想扔几一定可以扔几,因为这是可以训练出来的,你怎么能保证自己不具有那种天赋呢,对吧?
阿剑: 有朋友可能读到过 Cloudflare,它是一个很著名的云服务器厂商,他们专门写过一篇博客来解释自己是怎么生成熵的,就生成随机数的,答案是他们布了一面墙,一整整一面墙的,有很多个叫做熔岩灯的东西。这个熔岩灯是上个世纪 60 年代发明的,是一个英国人发明的。它是什么东西呢?它是下面有一个白炽灯,白炽灯上面放着一个容器,容器里面有水有蜡,下面的白炽灯加热的时候就会导致里面的蜡慢慢积累热量,然后不断的上浮,它失去热量之后又会下落。不断的上浮下落,不断的上浮下落。这个过程你可以认为它就是在抽象地说是在收集热力学的噪声。其实这个东西还是挺有启发性的,因为刚刚姚老师提到我们采集随机数的这个过程,希望这个过程是不可预测的,意思是没有人能提前预测到我采集的这个过程当中会发生什么事情。但也有另外一个角度叫做不可复现,就是我采集的这个过程,别人不太可能再把它重复一次出来。这个东西讲到最后的话,我觉得一定意义上最后都会追溯到我们怎么去收集热力学的这个噪声。这个热力学噪声比如说就像熔岩灯,热在分子之间怎么传递这个过程在我们看来是不太可能复现出来的。那如果我有足够多的熔岩灯,那给他们用足够精度的相机拍照,包括我们现在的这个操作系统,有一些你可以使用在主板上专门插入一个硬件的密钥,来作为随机数的生成器。它叫 TPM,等等等等吧。就是虽然我们知道我们离那个理想,就是说最终我们的整个这个采集随机数的这个过程,想要达到它完全不可预测,它完全不可复现,这个事情可能很难。但是这依然是一个我们需要尝试去做的事情。因为姚老师说,我们今天的整个密码学界或者说软件工业界在密码货币出现之后。它已经有了一个很大的不同。这个确实是事实。但是即使没有密码货币,我们今天的互联网的安全通信、身份认证也是建立在一系列依赖于随机数的密码学原语上的。所以这个依然是我们要去研究的事情。
曾汨: 好的,我们继续回到 Coldcard 这次事件本身。我们都知道 Coldcard 它的固件一直是开源的,然后有问题的代码其实从 2021 年 3 月就一直存在。也有大量的开发者、安全研究人员和用户在关注这个项目。但是这个项目自从 2021 年进入固件之后依然潜伏了很多年。为什么开源社区没有帮助更早地发现这个漏洞?我们是不是有点过于高估了开源这件事本身能带来的安全保障呢?
姚翔: 这个问题刚才有一些涉及。我想说的是对于开源软件来说,大家并不是仅仅是把代码开放出来就可以。这可能是一个蛮大的误解。代码开放出来,它意味着其实要做很多其他的工作。这个工作里面有一个很重要的是你开放出来是希望被同行来审计。但是这件事情本身怎么说呢?就是我们知道这一次的出问题的代码,可以理解成是 Coldcard 的开发的公司,它自己的一个单独的实现。我不能说主流,但是至少它不是一个被广泛使用的实现。或者说这个实现是一个孤立的实现。那么在这种情况下,你希望有人来为你提供免费的建议,我觉得是比较难的,因为它并不是一个在一般意义上的一个很比较具有公共性的东西。那在这种情况下,一个公司希望他把这个开放出来的代码,提供更强的安全性,它需要做一些工作。这些工作包括去找一些赏金猎人,也包括去做代码的审计。这些我觉得是必要的,不仅仅是说把代码开放出来,就说我开源了,这么简单。但其实我退回来,回到那种我不想面对的这种局面,但是也是真实的局面,就是有人说你看,代码就不应该开源。开源了就有问题。我不赞成这种声音。但是我觉得简单的代码开放也是远远不够的。它应该是有相应的配套出来一些东西。以及我看到最近在推特上的讨论,刚才节目前也闲聊到,就是有开发者其实在 2025 年的时候就给他们提出过这样的问题。因为这个事情还在发展当中,我也不想做一些评价,但是我倾向于相信他的这个表述,因为他提供了足够多的证据,所以我认为这个并不能说明开源社区失效了。一是,刚才说的,他没有做出足够的让他有效的努力。第二是可能有一些已经发生的事情我们不知道,以及第三就是这件事特别特别。
我不能说有趣,因为毕竟不是个很开心的事情,特别让人惊讶的事情吧。就是这个公司如果在 2025 年接到这个通知发现了这个问题,它能做的事情也非常非常的有限。然后这时候去修改代码反而是一个最危险的事情,可能。因为修改代码相当于暴露说自己的这一段代码有问题。在今天这个 AI 对所有代码库进行严密监控的情况下,你去修改自己的随机数生成,就很快的就会让大家去想你为什么要去修改它,反而会把自己暴露在危险当中,它也做不了别的事情。偷偷地去通知用户来转换资产。我觉得这个是这件事情非常诡异,也让人觉得很无奈的一个点吧。那要避免这个就只能在产品的一开始就把所有的工作做到一个相对到位的情况。但这个确实在这个世界当中它已经是 5 年以前的事情了。
曾汨: OK。那其实关于这一次事件,目前还有一种说法认为,攻击者可能是借助了 AI 来发现了这一个漏洞。然后在这个事件之后呢,比特币社区里面也有人发起了一个行动,叫做 Bitcoin Red Team,就是尝试使用多个 AI 模型来对比特币生态里面的钱包、密码学工具和其他一些开源项目进行大规模的扫描,然后把发现的问题再汇报给对应的团队。那这两个例子其实似乎展现了 AI 在于安全攻防当中的两种角色。我们也希望就这一点来展开聊一聊。请问姚老师,在你看来,AI 会给安全行业带来哪些变化?我们普通用户和开发者能够怎么样利用 AI 来加强安全相关的保证?
姚翔: 嗯,是很好的问题。这个问题也很大,因为我算是安全的从业者,但是和核心的圈子还是有一些距离。我知道这件事对整个的安全行业的影响是非常大的。这个工具它在一定程度上它提供了一定的公平性。这个事情是什么意思呢?就是因为安全行业它有它的特殊性。他的很多工具,他的很多资料并不是一个可公开获得的状态。历史事件当中,一般大的安全事件也不太会给外界去分享更多的细节。这个原因是你并不确定这个漏洞会不会在别的一个地方存在,有更多的人看到它,去利用它。所以安全行业的密码学,它是一个希望,就是用柯克霍夫的话说,敌人知道系统或者说一个系统的唯一的安全性,应该只依赖于密钥的保密。但是在安全的行业它的太多东西本来它其实是保密的,但是当出现了一个你说 AI 我想特指的是这个大语言模型,我想这个东西它给用户提供了极多极快的学习能力。这个对用户来快速地对自己的所使用的产品所用的软件。比如他自己想开发一个什么东西,他去寻找正确的代码库是有帮助的。这个帮助是巨大的,原因是在之前你想学习东西,你得有教材,然后后来有了搜索引擎,有了这个技术社区,但是他的那个学习曲线对于普通人来说是很难的。但是在有了这个,我想用核武器来比喻吧。它给一个普通人快速进入到一个对这个领域有一些了解,可以使用的这个能力的这个路径大大地压短了。在这个层面上我想说它提供了一种公平性。说完正面再也说一个反面的。就是我想这个问题是这个诉诸权威可能比浏览器时代更加严重。这一方面受限于 LLM,就是大语言模型的特性,以及这个软件的开放性,所以用户他在今天他可能更倾向于去请问 AI 工具意见,而不再询问专业人士的建议。然后专业人士相比较于这个模型,
他的知识一定没有那么丰富,那么全面,学习能力没有那么快,但是他有更强的经验和判断。他对一些显著的,比如说一些要素的丢失,他对一些幻觉,他有判断的意识,而用户当他把这个东西当作权威之后,有一些极端的场景下,因为它是一个基于概率的东西,它就有可能会产生一些错误的决策。他依赖了这个权威,他就不再寻求其他的帮助。那么除此之外,我还想说的就是,这一点产生之后,大家又变成了一个不协作的状态。或者说少协作的状态吧,会减少这种公开实践的讨论。我觉得这件事情还是要做的,否则我们之前所有积累的经验都会失效。因为比如说这个开发嵌入式软件,它就是有一些行业的规范,因为这个是一个很特殊的系统,它和一般的软件系统不太一样,它有很多的限制,它也有一些对安全性非常细节的要求。但是如果你让一个通用的大语言模型来做。它可能并不具有这样的能力。当然一般用户也不会把它训练成具有这方面的能力。然后一个工程师就会觉得自己无所不能。他觉得都是代码也没有什么不一样的。这样做出来的东西可能如果过去那些经验都是有效的,但他又没有利用这些经验,那我只能说就是大家就是走在一个不断创造熵的过程当中,就是增加很多的混乱。这是第三点。
第四点就是,我想这个也不用特别提,开始我想这个不用特别提,但是我还想提一嘴,就是不要跟 AI 聊天,谈论自己的密钥。也不要跟 AI 聊天说我现在怎么来构建我的密码学的方案。因为在今天我们对这个整个隐私性系统是怎么运作的,仍然处在一个极度不确定的状态当中。我们对这个历史数据能否被访问也是一个完全不确定的状态。所以就把它想成所有的对话都是会被公开的。基于这个来做提问,我觉得在今天要不断地有这样的意识,否则在未来某一天可能会有一个就是一个巨大的事件,也许某天会爆发,我不知道什么时候,我希望不会有,但是我总会有这样的担心。然后作为一个使用者,我想说一点,就是其实大部分的大语言模型对你去想尝试利用系统的漏洞,这件事是有防备的。他不会拒绝回答一些相关的安全问题。当然,如果你有经验,你可以不断的尝试或者去去构造一个等价的场景,让他来给你提供知识。但是这些毕竟都是商业模型,它能拦得住一般的用户,它拦不住专业的用户。就是在这个意义上这种知识和技能上的不平等仍然存在,然后我觉得这个就涉及上升到一些关于技术的问题。本身的一些特性的讨论上,这个和历史上发明原子弹时期一样,我觉得是有一些相关性的。然后我觉得这个技术的产生,它对安全领域,就是阿剑刚才提到的,不光是密码货币,所有的互联网安全性的基础都基于此。我觉得在这个背景下,关于这样技术工具的使用,会成为一些新的话题。那现实当中它就已经在不断地发生了。我甚至会怀疑在未来的这个计算机它会做一些代码的审查。完全是有可能的。就是它会拒绝去对一些它觉得有恶意的代码进行编译。
然后最后大家会回到一个有些人要决定什么是对什么是错的,那个环境里。但也可能是一种必要性。但我会想得比较多。我想回头来总结一下我刚才所说的。我觉得对普通的人,我觉得大家都不普通,我觉得就是说对认为自己只是用户的这个视角的人,就我自己并没有在开发产品,我也没有做任何这个软件行业,密码货币行业相关的事情,我只是单纯的关心,然后我也使用,关心我的资产安全,我想用一个放心的产品。我觉得有大语言模型的工具,总体来说是有益的。但是请注意,你把所有的对话都当作是一个有一天一定会公开的东西就好。或者说这个东西公开了你可能会难受,但是它不会对你有很大的影响,也可以。大概是这样一个视角吧,我觉得是比较合适的。
阿剑: 我想补充一句话。我自己作为一个并不研究 AI 的人,尽管我对它有一些原理上的了解,我不知道它能帮你解决多少你面对的生活或者是其他方面的问题,但是相信知识有单一的来源,这件事情本身是危险的。我觉得需要警惕的是这个,不要相信知识有单一的来源。
姚翔: 阿剑说得很好。因为刚才我都没有提到 AI 本身会受到攻击嘛。我觉得说起来可能会作为一种令人生厌的提醒。但是这个话既然已经说到这里了,我就马上说,它给你回答的可能是错的,或者是可能是进行设计过的,或者可能是希望你有某种倾向的。甚至在现在的这个体系下,你都没有办法证明这一点。
曾汨: 好的,那么节目的最后,我们回到普通用户最关心的问题。对于长期持有比特币的人来说,这一次的事件说明,即使你的助记词没有泄露,设备没有联网,备份保存得很好,依然可能因为生成助记词时候的底层漏洞而失去资产。普通用户也很难去亲自审查代码,也没有办法自己去判断内部的随机数是否真的可靠。那在这种信息和能力都不对称的情况下,我们作为普通用户应该如何降低风险,可以建立哪一些更加安全可靠的安全措施呢?
姚翔: 这个其实是一个老生常谈的话题,然后我们以前节目当中也都有涉及,以及我也觉得没有什么更多有新意的东西要分享。但针对这个事件,我觉得大家至少能做的是,如果你在使用任何相关的产品,包括软件的钱包,包括硬件签名器,包括甚至是你自己认为安全的那些生成密钥或者保存密钥的方式,你可以重新地去审视一下这个事情。这个事情我个人觉得可以作为一个值得花时间去学习的一件事情。你可以去和朋友讨论,你可以去和 AI 讨论,我觉得没有什么关系,因为其实不太会暴露你的这个当前的一些信息。重新去审视这些,去知道自己到底在使用一个什么样的产品。它是不是一个被广泛验证的一个状态?它在原理上有没有一些显著的问题?这个问题我觉得是可以去问的。然后具体到细节上,这件事就是一个很泛的问题。当然我可以说去用什么多签,我可以不主要依赖任何软件提供的这个熵自己去采集,比如说刚才阿剑提到了这个熔岩灯,然后我自己也觉得就是有些其实图像的,我不作为任何建议,但是我觉得图像生成的熵是值得信任的,这个就是随手去拍一些照片,然后你有有很多这样软件去从图像当中去采集熵,或者你就自己去看他的 RGB 值的数据,你从当中你自己先随机选一个位,然后从当中去不断地这样去采集,不断地去采集。它不是我们数学学上说的那种随机。但是如果你仅仅一次性去生成的密钥,我个人觉得是足够的。至少在今天这个语境下是足够的。但是能做的事情确实很有限。我必须很无奈地这么说,就是能做的事情比较有限。因为如果我要去买一个产品之前,我得先让 AI 帮我去把它代码审计一遍。我觉得这件事听起来非常的荒谬。因为他假设其实就是希望能让没有那么多技术知识的人可以用得很好。
但是到今天回归到这一步,反而我觉得是一个蛮可悲的事情。那作为从业者,我的想法是说,我就会换一个角度想说,那我们还能做什么能让大家更加放心地去不是说要信任,而是说提供更多可供参考的这些东西。就比如说我举个例子,有一个对各种硬件钱包的这个熵的生产有一个评估。那么这个评估本身也不是说发布出来就希望每个用户都相信这个评估,而是你一旦发现什么问题,他厂商他是没有跟他回避的。他一定会对他要有所回应。他会形成某种公共讨论。我觉得这个是很关键的。他并不是一种建立新的权威或者是建立一种新的这种信任关系。我想说是他其实是作为从业者应该采取的一个态度吧。就是有更多的这种责任的意识。当然从根源上我觉得要有一个良性的互动。除了发个 bounty 的这种技术以外,我确实也想不到更好的解决这个问题的办法。这个问题来说,我确实对普通用户这个角度是没有什么更好的建议的。因为我觉得大部分人的想法就是,我买了一个 Coldcard,然后出了问题,然后我就在想为什么我买 Coldcard。可能是怎么怎么样,谁推荐的,或者我在哪里看到它好,或者谁谁谁也在用,我看见了,或者它卖得最好。这些理由我觉得都很合理。然后就会想,那我为什么就刚好遇到了这个呢?那我下一次怎么去选择?我觉得这个问题是挺难解的,就真的很难回答。作为一个普通用户,我自己也不会去让 AI 去,如果在没有这个事件发生,我也不会让它去审查这个代码库。就不会去想这件事情,但从今天开始我想可能大家要有一种更加积极的一种心态,就是之前是没有说有问题就是没问题,就对这个软件行业进行也不能说叫无罪推定吧,但是至少是一种无问题的倾向,搭便车的心态,我觉得今天开始大家是倾向于做一种有罪推定,我觉得虽然可能会消耗很多资源,但在密码货币之间可能是值得的,对。
阿剑: 我猜有一些用户可能会在这次事件之后,对签名器这个东西本身持有一定的怀疑。但是我自己希望在这里为签名器这个东西本身做一个辩护。在当下这个人们已经高度依赖于互联的网络和计算设备的生活当中,基于密码学的安全性已经是人们生活中不可或缺的东西。我们都高度依赖于它,依赖于各种各样的软件和硬件实现,依赖于各种各样的密码学的库,密码学的原语。那签名在这个过程当中,它不仅在密码货币上具有决定性的重要性,在其他领域它也有它的重要性。本身我们对签名过程的安全性的研究也是在不断进步的。就以比特币为例,很多年以前我们发现如果我能劫持你的硬件签名器的话,那么我可以篡改它的固件来去做一些事情。那给定硬件签名器本身是不联网的,该怎么做这件事情呢?答案是篡改你的 nonce 本身的这个生成的过程,来使得你会产生 nonce 的复用,或者是在 nonce 当中本身暴露你的机密信息。这个听起来是不是很吓人,或者说听起来是不是哦,那硬件签名其实这个是不是变得更可疑了?我想说的是恰好相反。正是因为我们对这个过程的安全性的认识是不断深入的,所以我们才需要一些。专业的这个设备来去帮助我们去做一些事情。而且我想强调的是,这个过程基于当代的这个非对称密码学本身的特殊性。这是难以避免的。你可以想想,如果完全不用硬件签名器,那你其实也是要用软件的签名器,对不对?如果你完全不用计算设备,我们能够用纸质的计算设备或者模拟计算机,自己算出一个 256 位的椭圆曲线公钥的签名吗?这是算不出来的。我们没有这个能力,所以我们只能是面对的确有一个非常健康的意见,是对签名设备是不应该完全信任的。
尤其在这一次事件当中有一些不完全信任 MK3 的这些设备,他们的资金,如果他们投了足够多的骰子,或者是他们使用了一个很强的 passphrase。那么他们的资金能够得到保护。对自己所用的工具本身保持警惕是一个非常有益的思维,但是我觉得大家不应该因噎废食,就此止步。因为签名器,因为私钥自己持有,然后自己发起安全的通讯这件事情,我相信会变得越来越重要。包括在未来,我们看到更多的这个比特币的软件钱包产品,他们尝试使用比特币脚本本身的这个特性来给用户提供这种容错机制,提供继承的便利性的时候,签名器仍然将在其中发挥重要的这个作用。所以我觉得大家还是不应该,因此就觉得签名器就是一个完全没有必要的东西。完完全全是多余的东西。如果你完全放弃签名器的话,我觉得你会放弃很多很多东西。并且在这个过程当中是不是让自己变得更安全了,我觉得是值得怀疑的。至少在我自己的观察当中,签名器的安全性是在持续进步的。
姚翔: 我觉得阿剑的这个补充很好,提供了一些很积极的信号和判断。作为安全从业者,就从来不太会有积极的视角,但我也仍然认可阿剑刚才的这个表述,就是尽管我们离完美都很遥远,但是我们知道什么比什么更好,就是哪些东西是相对好的,尽管它可能存在一些问题,那我们就把这些存在问题的部分去做出更多的努力。我觉得这是一个比较务实的态度。我也想说大家对比特币本身的这种信心,但我不会说希望大家去保留这个信心。我只想说,大家问一个问题,就是在已知的理论层面,它有造成任何更多的负面的影响吗?我也不会答。大家自己想一想这件事在根源上它意味着什么。但是这个并不代表人们的信心会产生什么变化。本身没有出现问题,大家可能也减少了信心,减少信心之后可能也会减少投入,这个东西可能会进入某种不好的循环里。但我想正因为此,我们才可能需要一些更加积极的态度,这个积极的态度可以帮我们抵抗这种向不好方向的一种循环吧。
曾汨: OK,我再做一点补充。其实关于普通用户的安全措施,就像姚老师说的,其实最核心的,或者最后最老生常谈的还是那几样,多签,然后联合保管。我们其实之前和姚老师专门录过一期播客,专门聊关于继承的问题,那里面就专门聊到了关于联合保管的问题,所以感兴趣的听众也可以回顾那一期播客,包括我们在《亿聪哲史》的第六期播客里面,我和阿剑老师很详细地聊到了大家在挑选硬件签名器和软件签名器,以及在创建自己的钱包的时候需要注意的各种事项。也非常强烈地推荐大家再去回顾那一期播客。然后关于这一次的 Coldcard 事件,我想分享另一个我看到的比较有意思的一个观察,有一个韩国社区的推特上的用户,他分享了一个文章说,韩国用户当中使用 Coldcard 的用户其实不少,但是几乎没有在这一次事件中被影响到。究其原因,是因为韩国的比特币社区的影响者,一直在强调用户使用掷骰子来生成自己的助记词。而如果你在使用 Coldcard 的产品的时候,用了掷骰子生成助记词的这种方式,你就很巧妙地避开了硬件钱包里面本身的这个随机数发生器所带来的影响。所以这个是我观察到一个很有意思的一个事情吧。然后像 Jimmy Song 他在推特上说他去过韩国参加比特币活动好几次,但是去过了好几次之后,他发现韩国社区的绝大部分人,他都不知道叫什么名字。他觉得韩国社区在这一点做得很好,因为比特币设计上每一个人对自己的名字做得非常的重视,哪怕来参加活动用的都是化名,他根本不知道和自己交流的那些人叫什么名字。我觉得这也是一个值得我们观察值得我们反思的一个点吧,我觉得很有意思分享给大家。然后今天的播客我们就录到这里结束了。非常感谢姚老师带来的分享。
也希望这次讨论能够帮助大家更加完整地理解这场事故,并重新审视自己的资产安全。感谢大家收听《亿聪哲史》。我们下期再见。拜拜。
姚翔: 谢谢。再见。
