原文标题:《区块链黑暗森林自救手册》
原文作者:余弦,慢雾安全团队
引子
首先,需要先恭喜你的是:你看到了这本手册。我不清楚你是谁,但如果你持有加密货币或对这个世界有兴趣,未来可能会持有加密货币,那么这本手册值得你反复阅读并谨慎实践。
其次,需要有心理准备的是:本手册的阅读需要一定的知识背景,我尽量照顾初学者,但很难。我希望初学者不必恐惧这些知识壁垒,因为其中大量是可以「玩」出来的。如果你遇到不懂的知识点,需要扩展了解的话,建议你用好 Google。并强烈建议你掌握一个安全原则:网络上的知识,凡事都参考至少两个来源的信息,彼此佐证,始终保持怀疑。
是的,始终保持怀疑!包括本手册提到的任何知识点:)
区块链是个伟大的发明,它带来了某些生产关系的变革,让「信任」这种宝贵的东西得以部分解决。这已经很难得了,不需要中心化、不需要第三方角色,有些「信任」基于区块链就可以得到很好解决,不可篡改、按约定执行、防止抵赖。但,现实是残酷的,人们对区块链的理解会存在许多误区。这些误区导致了坏人轻易钻了空子,频繁将黑手伸进了人们的钱包,造成了大量的资金损失。这早已是黑暗森林。
在区块链黑暗森林世界里,首先牢记下面这两大安全法则:
1. 零信任。简单来说就是保持怀疑,而且是始终保持怀疑。
2. 持续验证。你要相信,你就必须有能力去验证你怀疑的点,并把这种能力养成习惯。
注:本手册中,安全法则就这两条,其他都可以认为是这两条推论出来的安全原则。
好,引子部分就到这。下面我们从一张图开始,进入到这个黑暗森林,看看我们都会遇到哪些风险及我们应该如何应对。
一张图
在仔细看后文之前,你可以先粗略过下这张图。这张图是你在这个世界(无论你如何称呼这个世界,区块链、加密货币还是 Web3 都行)里关键活动有关的内容,从流程上包括三大部分:创建钱包、备份钱包及使用钱包。
我们顺着这三大流程,将涉及到的每个关键点展开分析。
创建钱包
钱包最最最核心的就是那个私钥(或助记词)。
私钥长这样:
0xa164d4767469de4faf09793ceea07d5a2f5d3cef7f6a9658916c581829ff5584
助记词长这样:
cruel weekend spike point innocent dizzy alien use evoke shed adjust wrong 注:用以太坊举例,关于私钥/助记词的基础知识请自行扩展。
私钥即身份,如果私钥丢了或被盗了,那么这个身份也就不是你的了。钱包应用其实很多,知名的也不少,我并不打算也不可能一一介绍。但该手册确实会提到一些具体的钱包,请注意,能被提到的必然是我有基本信任的,但我不担保你在使用过程中可能出现的安全问题或目标钱包可能出现并不在我预期内的安全风险(后文我不会再不断去废话这些,引子里提到的两大安全法则希望你牢记心中)。
钱包从应用分类来说主要包括几种:PC 钱包、浏览器扩展钱包、移动端钱包、硬件钱包及网页钱包等。从触网与否来说主要可以分为冷钱包和热钱包。当我们要进入这个世界,首先要思考将拥有的钱包的用途,用途决定了你将用哪个钱包,同时用途也决定了你会如何对待这个钱包。
无论你选择什么钱包,但至少有一点可以肯定的:在这个世界玩久了后,你不可能只有一个钱包。
于是这里我们又需要记住一个安全原则:做好隔离,也就是鸡蛋不要放在一个篮子里。一般来说使用越频繁的钱包,自然也加大了出问题的风险。时刻牢记:面对一个新事物时,先准备个单独的钱包,用单独的小资金去玩一段时间。除非你已经如我这般,经历无数,对许多事物都了然于心。但,常在河边走,哪有不湿鞋呢?
· Download
单这么简单的一点,其实也不简单,原因:
1. 许多人(真是许多人)找不到正确的官网,正确的应用市场,于是安装了假钱包。
2. 许多许多人对下载了的应用不知道如何确认是否被篡改过。
于是,出师未捷身先死。还没来得及进入这个世界,就已经钱包空空了。
针对上面的第 1 点,找到正确的官网是有技巧的,比如:
· 行业知名收录,如 CoinMarketCap
· 多问一些比较信任的人
好,上面这几点得到的信息可以全部结合起来参考,互相佐证,最终真相只有一个:) 恭喜你,找到了正确的官网。
接着,你要下载安装应用了,如果是 PC 钱包,根据官网提供的下载链接,下载后需要自己去安装。但在安装之前,建议做下是否篡改的校验工作,虽然这个做法并无法防止源头就被完全篡改的情况(比如官方自己内部作恶、内部被黑、官网被入侵替换了相关信息等等),但可以防止如:源头被部分篡改、被中间人劫持篡改等这些情况。
是否篡改的校验,实际上就是文件一致性校验。常见的方式有两种:
· 一种是哈希校验,比如 MD5、SHA256 等,MD5 绝大多数情况下够用,但存在被哈希碰撞的极小风险,所以业内一般选择 SHA256,够用且够安全。
· 另一种是 GPG 签名校验,这个其实也很流行,强烈建议掌握 GPG 工具、命令、方法,虽然对于新人来说有那么些费力,但上手后,相信我,你会很快乐的。
话虽至此,其实业内这样做的项目方并不多,所以一旦遇到,真是难能可贵,弥足珍惜,比如一款比特币钱包 Sparrow Wallet,下载页面的「Verifying the Release」简直良心了,提到的两种方式都有清晰指南,可以直接参考学习:
https://sparrowwallet.com/download/
这个页面提到的 GPG 工具有两个:
· GPG Suite,macOS 下运行的。
· Gpg4win,Windows 下运行的。
如果你细心观察,你会发现这两个 GPG 工具的下载相关页面其实都有给出两种方法的一致性校验说明,但不好意思的是,并没手把手教你如何校验。估计吧,都是认为你会是聪明人,该补上的知识你已经补上了:)
如果是浏览器扩展钱包,比如这世界家喻户晓的 MetaMask,你唯一有机会注意的就是目标扩展下载页面里的用户数多不多、评分情况如何,比如 MetaMask 在 Chrome 网上应用店里,用户数可是超过一千万的,同时有两千多用户评分的,虽然最终评分并不高。有人要说这不可以刷出来吗?这位朋友,是这样的,刷,我相信,不过刷的量如此之巨大,当各方是傻子呢。
如果是移动端钱包,判断方式类似扩展钱包,不过需要注意的是,iPhone 的 App Store 是分区的,加密货币在中国大陆被驱赶得不行,所以如果你用 App Store 中国区账号下载到了钱包,建议只有一个:别用,换成如美区的 App Store 账号下载吧。另外,通过正确的官网也能引导到正确的下载位置(比如全球知名的 imToken、Trust Wallet 等,官网安全一定要做好,官网都被黑了,那这安全责任就真大了)。
如果是硬件钱包,简单来说,可以从官网源头的引导下购买,不要直接去在线商城,到手后也需要留意是否存在被异动手脚的情况,当然有些针对硬件包装的异动是很高明的,不一定都能看得出。此时建议:无论如何,使用时,先连续至少三次从头开始的创建,记录下生成的助记词、相关钱包地址,不会重复就行。
如果是网页钱包,非常不建议使用这种在线的钱包,除非你不得已,那么识别好是官方的后,速战速决吧,千万别有任何感情依赖。
· Mnemonic Phrase
一般来说,我们创建了钱包后,直接打交道的关键信息是助记词(而不是私钥),毕竟助记词是方便人类记忆的。助记词是有标准约定的(如 BIP39),这就对助记词提了要求,比如一般 12 个英文单词,也可以是其他数量(3 的倍数),不过不会超过 24 个单词,要不然太复杂也就不助记了,数量少于 12 的话,安全性也不靠谱,12、15、18、21、24 都好说。不过从业内习惯来说,一般流行的是 12 位,安全性足够,有的安全严谨到变态的如 Ledger 这类硬件钱包,24 位标配走起。还有除了英文单词,也可以是其他的,比如中文、日文、韩文等等。但也不是什么单词都可以,有一个固定 2048 个单词列表,具体参考:
https://github.com/bitcoin/bips/blob/master/bip-0039/bip-0039-wordlists.md
创建钱包时,助记词的出现是非常敏感的,请留意你身边没有人、摄像头等一切可以导致偷窥发生的情况。同时留意下助记词是不是足够随机出现,正常来说这些知名钱包生成的助记词随机数是绝对足够的,这不以防万一?你真的很难知道,拿到手的钱包到底有没有万一的猫腻。你也不要嫌麻烦,这些安全小习惯形成后,相信我,你真的会很快乐。最后,有的场景下,你甚至可以考虑断网来创建钱包,尤其是你准备把该钱包当成冷钱包使用时,断网简直就是暴力美学。
· Keyless
Keyless,顾名思义是无私钥的意思。在这我们把 Keyless 分为两大场景(注意,这里的区分不代表业内公认区分方式,只能说是方便我讲解):
· Custody,即托管方式。比如中心化交易所、钱包,用户只需注册账号,并不拥有私钥,安全完全依托于这些中心化平台。
· Non-Custodial,即非托管方式。用户唯一掌握类似私钥的权力,但却不是直接的加密货币私钥(或助记词)。比如依托知名 Cloud 平台做托管、认证授权,此时知名 Cloud 平台成为木桶的那块短板。还有利用了安全多方计算 (MPC) 来确保不存在单点风险,同时也结合知名 Cloud,将用户体验做到最好。
对我来说,Keyless 的几种方式我都有使用。实力雄厚及口碑良好的中心化平台体验好,只要不是因为自身原因导致的被盗币(比如账号相关权限被盗),这些平台也会兜底赔付。至于 MPC 为主的 Keyless 方案是我觉得很有前景且应该尽快普及的,我用过不错的如(ZenGo、Fireblocks、Safeheron)。优势很明显,我这简单提几点:
· MPC 算法工程实践在这些知名区块链上,越来越成熟,只需针对私钥开展即可。
· 一套思路可以解决不同区块链的多签方案差异巨大的问题,使其在用户感知上通用,这是我们常说的:通用多签。
· 可以确保真实的私钥从不出现,通过多方计算解决单点风险。
· 结合知名 Cloud(或有人提的 Web2)让 MPC 不仅安全且体验更顺滑。
优点明显,但缺点也是有的,我也简单提几点:
· 满足业内公认标准且开源的,这方面的成熟度还远不够,各位仍需努力。
· 有不少人说基本只玩以太坊系列(或者说基于 EVM 的区块链),那么 Gnosis Safe 这种智能合约方式的多签方案也就够了。
无论哪种方式,只要是你觉得安全可控的、用起来舒服的,那么都是好方式,仁者见仁智者见智。
好,创建钱包的相关安全注意点就先介绍这些,有一些通用性的安全问题会统一在之后介绍,先不着急:)
备份钱包
许多挺厉害的人都在这踩坑了,其中包括我,常在河边走,湿鞋我也认,好在这不是个大资产钱包,并且最终我在慢雾的兄弟帮我破解解决了。这也是厉害的地方,我没备份好,我踩坑了,但我却有厉害的资源能帮我解决这个坑。不过我也会冒冷汗,人之常情。冒冷汗的感觉你肯定也不喜欢,那就集中精力学习下如何安全地备份钱包吧。
· 助记词/私钥类型
我们所说的备份钱包,其实归根结底是备份助记词(或私钥,为了方便介绍,后文一般情况下只提助记词)。我们拿到的助记词其实可以主要分为几种类型:
· 明文
· 带密码
· 多签
· Shamir's Secret Sharing,简称 SSS
这几种类型,我简单展开说说。
明文,很好理解,那 12 个英文单词你拿到了,里面的资产就是你的了。其实这个时候可以考虑做些特别的「乱序规律」,甚至把某个把单词替换为其他的单词。这样做对于坏人来说头疼了,但如果这个「规律」你自己忘记了,就轮到你头疼了。千万不要觉得你头疼是不可能的,相信我,一年、两年、五年后,记忆这东西真的会错乱。几年前,我玩 Ledger 硬件钱包时,就踩坑了,助记词 24 个单词,我抄写备份时打乱了顺序,几年后我忘记了排序规律,且不记得自己是不是替换了其中的单词。如前面说的,我的问题后来解决了,专门的破解程序碰撞出了正确的助记词顺序且纠正了其中的个把单词。
带密码,根据标准,助记词是可以带密码的,助记词还是那样的助记词,只是带上密码后会得到不一样的种子,这个种子就是之后拿来派生出一系列私钥、公钥及对应地址。此时,你不仅要备份好助记词,这个密码也千万别忘记了。顺便说下,带密码的形式,除了配套助记词,私钥也有相关标准(如 BIP38),还有如以太坊系列常见的 Keystore 文件。
多签,可以理解为目标资金需要多个人签名授权才可以使用,多签很灵活,可以设置审批策略,比如 3 个人都有钥匙(助记词或私钥),需要满足至少 2 人的签名审批,目标资金才可以使用。每个区块链都会有自己的多签解决方案,比特币系列的很好理解,知名的比特币钱包都原生支持多签。不过以太坊系列的,主要通过智能合约来实现多签,如 Gnosis Safe。另外,除了这些比较普遍的多签方案,还有一类正在流行的:MPC(Secure Multi-Party Computation),即安全多方计算,和传统多签体验接近,但原理却很不一样,通过 MPC,可以实现通用多签,并不需要不同链不同的多签方式。
SSS,Shamir 秘密共享方案,作用就是将种子分割为多个分片(常见的每个分片有 20 个单词),恢复钱包时,需要使用指定数量的分片才能恢复。具体参考业内最佳实践:
https://support.keyst.one/v/chinese/gao-ji-gong-neng/zhu-ji-ci/chuang-jian-dao-ru-fen-pian-zhu-ji-cihttps://wiki.trezor.io/Shamir_backup
用了多签、SSS 这类方案,其实会放心很多,避免了单点风险,但管理上也相对复杂了,而且这很多时候会涉及到多个人。便捷与安全是永恒的矛盾,具体看自己。但在法则、原则上千万别偷懒。
· Encryption
加密是个非常非常大的概念,无论对称、非对称还是其他什么高级的,只要加密了后,多年以后,你或者你的灾备人可以很好解开,而其他人解不开的加密就是好加密。
根据「零信任」这个安全法则,当我们在备份钱包时,每个环节都要假设可能会被入侵,哪怕物理环境,如保险箱。别忘了,这个世界除了你自己,并没有其他人是完全可信的,其实有的时候自己也不可信,比如记忆可能会淡忘、错乱等。但我不会把这个世界假设的如此可怕,否则最终还是会把事情搞砸了。
备份时一定要特别考虑灾备。灾备主要就是要避免单点风险,万一你没了,万一你备份目标所在的环境没了,该怎么办?所以重要的东西,一定要有灾备人;重要的东西,一定有多处备份。
那么,灾备人的选择我就不废话了,看你信任谁吧。我重点提提多处备份。先看看备份位置的几个基本形态:
· Cloud
· Paper
· Device
· Brain
Cloud,许多人谈云备份色变,似乎黑客真的就上天入地,来无影去无踪的。其实攻防对抗永远都是成本对抗,看谁投入的大,无论是人才还是钱。对于我来说,我会比较信任 Google、Apple、微软等提供的相关云端服务,因为我知道他们的安全团队是如何实力,安全投入是如何之大。但除了对抗外部黑客入侵,我还很关心内部安全风控的能力及隐私数据保护有关的约束力。我比较信任的几个,都算是把这些我在意的安全风险规避得不错的。但凡是绝无绝对。如果我选择这些云来备份我非常重要的数据(如钱包),我一定还会给钱包再做至少一次加密的。
我强烈推荐掌握 GPG,除了前面提到的「签名验证」用途之外,加解密方面安全性也足够强了。关于 GPG 这块的入门可以参考:
https://www.ruanyifeng.com/blog/2013/07/gpg.html
好,你掌握了 GPG:) 现在你已经在离线安全环境下用 GPG 加密了你的钱包(助记词或私钥)有关内容,你可以把加密后的文件直接扔到这些云服务里去了,保存好,没事的。但这里我需要提醒下,你 GPG 的私钥别丢了、私钥密码别忘记了...
到这,安全带来的麻烦似乎还没适应,GPG 好不容易入门了,你还得备份好 GPG 的私钥及私钥密码。其实真到这步了,你也熟悉了,再备份这点东西其实也就不麻烦了。这点我不展开,留给实践出真知的你。
如果你想偷懒,还有一种方案是可以考虑的,只是安全性上会打点折扣,我不好衡量具体折扣多少,但有时候有的场景下我也会偷懒,于是我会考虑用知名的工具来做辅助。这个工具就是 1Password。1Password 新版本已经支持直接保存钱包相关内容,如助记词、密码、钱包地址等,这方便用户。其实其他同类型工具(如 Bitwarden)也可以,只是使用起来不像这样方便。
Paper,许多硬件钱包都会附带几张质量上乘的纸卡片,你可以将助记词(明文、SSS 等形式的)抄写在上面。除了纸质的,还有钢板的(抗火抗水抗腐蚀,当然我没验证)。助记词抄写完成后,会做一次验证,没问题后,放进你觉得安全的位置,比如保险箱。其实我个人挺喜欢 Paper 的,Paper 所处环境不错的话,寿命远大于电子设备。
Device,各种设备吧,电子设备是常用的一种,电脑、iPad、iPhone、移动硬盘、U 盘等都可以拿来做备份,看个人喜好。然后设备间的安全传输,让我比较有安全感的是:隔空投送 (AirDrop)、USB 等这类点对点且挺难出现中间人劫持情况的方式。只是我天然对电子设备不放心的一点是多年后可能就坏了,所以会保持每年至少一次的检查习惯。有一些重复做法(如加密)参考 Cloud 小点里的说法就行。
Brain,脑记很爽很刺激,其实每个人都有自己的「记忆宫殿」的,这玩意不玄乎,可以训练,熟能生巧,加深记忆。有不少东西确实还是脑记好,至于到底是不是只唯一用脑记看你自己。反正注意两种风险:一是时间会让记忆淡忘或错乱;二是自己可能出意外。这块不多说了,请自行扩展。
现在你都备份好了。加密不能太过分了,否则多年以后等于「同归于尽」,因为到时候你可能自己都解不开。根据安全法则「持续验证」,无论过不过分的加密及备份方法,一定要做到定期不定期地验证,验证频率得看你的记忆,有时候转头可能就忘记了。验证不代表一定都要完整解开看看,只要整个过程不会错,采用部分验证也是可以的。最后,也需要注意验证过程的机密性及安全性。
好了,长舒一口气,其实入门是最难的,以上你都准备好后,咱们开始真正进入这个黑暗森林吧:)
使用钱包
当你创建及备份好钱包后,真正的大挑战才来了。除非你非常的佛系,不怎么折腾持有的价值资产,平时也不会去玩以太坊系列的 DeFi、NFT、GameFi 等智能合约有关的项目,或者说当下喜欢提的 Web3。那么实际上你的资金是挺安全的。
· AML
嗯,也只是「挺安全」,因为这里还是有风险的,所谓「人在家中坐、祸从天上来」。为什么这样说呢?你想呀,你最开始的加密货币是从哪里来的?不会是凭空出现的吧?那么在加密货币活动可能中,你拿到的加密货币都可能遇到 AML(Anti Money Laundering) 即反洗钱风控。也就是说你此刻持有的加密货币可能是不干净的,甚至如果足够倒霉,还可能存在被直接在链上冻结的情况,比如公开报告中 Tether 曾经在执法单位的要求下冻结了一些 USDT 资金。被冻结列表可以看这:
https://dune.xyz/phabc/usdt---banned-addresses
验证是否被 Tether 冻结,可以在 USDT 合约地址进行:
https://etherscan.io/token/0xdac17f958d2ee523a2206206994597c13d831ec7#readContract
在 isBlackListed 输入目标钱包地址即可判断。USDT 所在的其他链大体同理(别较真)。
但你的比特币、以太坊是不会出现链上冻结情况的,也许未来出现了这个情况,那这点本来非常坚定的去中心化信仰可能也就没了。我们现在经常听到的加密货币冻结实际上绝大多数并不是发生在链上的,而是发生在中心化平台里,如中心化交易平台(Binance、Coinbase 等)。你的加密货币在这些中心化平台里,意味着你并不是真正意义上持有这些加密货币,中心化平台冻结的其实是你的账号,尤其是你的交易、提币权限。冻结这个概念其实很容易对圈外人造成无解,于是出现一些很烂的自媒体胡乱解读及散播比特币的各种阴谋论。
虽然你的比特币、以太坊等不会在链上被冻结,但如果你的这些加密货币本身就涉及到相关执法单位在处理的案件,一旦你的加密货币转移进中心化平台,这些中心化平台就有可能因为 AML 等要求将你的加密货币冻结。
为了比较好地避免 AML 问题,需要选择口碑好的平台、个人等作为你的交易对手。别瞎搞基本问题不大。如果要深度地解决这些问题实际上也是有不少办法的,比如以太坊系列上,几乎所有坏人及特别在意隐私的人都会选择 Tornado Cash 进行混币。更多的方法就不提了,因为这些方法实际上也会被用来作恶。
· Cold Wallet
冷钱包有好几种使用方法,对于钱包本身来说是不联网的,那么就可以认为这是个冷钱包。那么不联网如何使用?首先,如果仅仅是接收加密货币,问题不大,配合个观察钱包体验就已经挺不错了,比如 imToken、Trust Wallet 等都可以直接添加钱包地址,成为目标钱包地址对应冷钱包的观察钱包。
如果冷钱包要发送加密货币,常见的方式有几种:
· QRCode
· USB
· Bluetooth
这几种都需要专门的应用(这里称之:Light App)搭配冷钱包使用,这个 Light App 是联网的,包括前面提到的观察钱包。我们只需明白其中本质原理就会明白这些方式了。本质是:最终只需想办法把签名后的内容广播上链。我大概解析下过程:
· 待签名的内容由 Light App 通过这些方式传输给冷钱包。
· 签名由拥有私钥的冷钱包搞定后再通过这些方式传输回 Light App。
· Light App 将签名后的内容广播上链。
所以这里无论是二维码 (QRCode)、USB、还是蓝牙 (Bluetooth) 等方式,用途就是如上所说。当然不同的方式会有不同的细节,比如二维码信息容量是有限的,遇到签名数据很大的时候就得拆分。
这样使用似乎麻烦了点,不过习惯了就好,甚至满满安全感。但,千万别把安全感加满,因为这里还是有风险的,已经许多案例是因为这些风险而导致损失惨重。风险点如:
· 转币的目标地址没严格检查,导致币转给了其他人。人都是有惯性或惰性的,比如很多时候检查一个钱包地址主要就看开头、结尾几位是不是正确的,而没有几乎完整检查。于是坏人就激动了,专门用程序来跑出头尾几位一样的地址,然后通过一些手法把你的转币目标地址给替换为他控制的地址。
· 授权相关币种给了未知地址,通常来说授权是以太坊系列智能合约代币的机制,就是那个 approve 函数,一个参数是授权给目标地址,另一个参数是数量。许多人不了解这个机制,于是就可能把无限数量的代币授权给目标地址,此时目标地址就有权限把这些代币转走了。这就是所谓的授权盗币,手法还有其他变种,这里就先不扩展了。
· 一些看去不重要的签名,实际上藏着巨大的陷阱,这点也先不展开,之后会有解析。
· 冷钱包可能并没给你足够的必要信息展示,导致你大意了、误判了。
这一切都可以归结为两点:
· 所见即所签这种用户交互安全机制缺失。
· 用户的有关知识背景缺失。
· Hot Wallet
相比冷钱包,冷钱包有的风险热钱包基本都会有,除此之外,热钱包多了个:助记词(或私钥)被盗风险。此时的热钱包要考虑的安全就多了,比如运行环境的安全,如果运行环境有相关病毒,那么就有被盗风险。还有热钱包如果存在某些漏洞,通过漏洞也可以直接盗走助记词。
热钱包除了常规的转币功能外,如果要与那些 DApp(DeFi、NFT、GameFi 等)交互,要么直接用自带的浏览器访问,要么通过 WalletConnect 协议与 PC 浏览器打开的 DApp 交互。
注:本手册提到的 DApp 默认指运行在以太坊系列区块链上的智能合约项目。
默认情况下,这样的交互是不会导致助记词被盗的,除非钱包安全设计本身有问题。从我们的安全审计及安全研究历史数据来看,存在钱包助记词被目标页面恶意 JavaScript 直接盗取的风险。但这个情况比较罕见,因为这实际上属于极其低级的错误,知名钱包都不大可能会犯这种错误。
这里我最担心的问题实际上都不是以上这些,这些对我来说都可控(你也可以的),我最关心/担心的问题是:知名钱包的每次版本迭代是如何确保不会被植入恶意代码或后门?这个问题言下之意很清楚:当前的钱包版本我验证了没什么安全问题,我敢放心用,但我不知道下一个版本安全性如何,毕竟,我或者我的安全团队不可能有那么多时间与精力都去做验证。
这里所说的恶意代码或后门造成的盗币事件已经好几起了,如曾经的 CoPay、近期的 AToken 等,具体事件可以自行搜索了解。
对于这种情况,作恶主要有几种方式:
· 钱包运行时,恶意代码将相关助记词直接打包上传到黑客控制的服务端里。
· 钱包运行时,当用户发起转账,在钱包后台偷偷替换目标地址及金额等信息,此时用户很难察觉。
· 破坏助记词生成有关的随机数熵值,让这些助记词比较容易被破解。
安全这东西,无知者无畏、知者敬畏,许多点是细思恐极的。所以对于存有重要资产的钱包,我的安全原则也简单:不做轻易更新,够用就好。
· DeFi 安全到底是什么
当我们提 DApp 时,可能是 DeFi、NFT 或 GameFi 等等,这几个的安全大多是相同的,但会有自身的特别点。我们这里以 DeFi 为例先讲解下,当我们提 DeFi 安全时,到底指的是什么?业内几乎都只看智能合约部分,似乎智能合约安全了也就没事了。其实远远并非如此。
DeFi 安全至少包括如下几部分:
· 智能合约安全
· 区块链基础安全
· 前端安全
· 通信安全
· 人性安全
· 金融安全
· 合规安全
智能合约安全
智能合约安全确实是安全审计最重要的切入点,慢雾针对智能合约的安全审计点可以参考:
https://www.slowmist.com/service-smart-contract-security-audit.html
对于高级玩家来说,如果智能合约部分本身安全性可控(无论是自己能安全审计还是读懂专业机构的安全审计报告),那么也就无所谓其他部分的安全了。可控是个很有差异的理解,有的得看玩家实力。比如说智能合约权限过大的风险,玩家是有要求的,除非项目方本身实力雄厚及口碑良好,完全中心化也都无所谓。但对于那些不大知名的、有争议的或新出现的项目,如果你说这个项目的智能合约有权限过大的风险,尤其是这种权限还可以影响你的本金或收益,你肯定就不愿意了。
权限过大这种风险是很微妙的,很多时候权限这东西是方便项目方做相关治理及风险应急的。但对我们来说,这就是人性考量了,万一项目方作恶呢?于是业内有了折中的实践:增加时间锁 (Timelock) 来解决一些权限过大的风险,比如:
Compound,这个老牌知名的 DeFi 项目,它核心的智能合约模块 Comptroller 及 Governance 的 admin 权限都加了 Timelock 机制: Comptroller(0x3d9819210a31b4961b30ef54be2aed79b9c9cd3b) Governance(0xc0da02939e1441f497fd74f78ce7decb17b66529) 的 admin 地址是: Timelock(0x6d903f6003cca6255d85cca4d3b5e5146dc33925)
链上可以直接看到 Timelock 的时间锁(delay 参数)是 48 小时(172800 秒):
也就是说,如果 Compound 的 admin(项目方)需要变更目标智能合约的一些关键值时,这笔交易上链后会有记录,但必须等到 48 小时后才可以最终完成执行。这意味着,只要你愿意,你是可以审计 admin 的每一次操作,你至少有 48 小时来反应。比如如果你不放心,你可以在 48 小时内把资金撤走。
还有一种削弱项目方权限过大风险的做法是:将 admin 多签了,比如用 Gnosis Safe 进行多签管理,这样至少不会出现一言堂。这里需要注意的是,多签可以是「皇帝的新衣」,比如一个人掌握了多把钥匙。所以目标项目的多签策略需要公示说明清楚,钥匙都由谁保管,保管钥匙的角色也一定是有口碑的。
这里需要特别注意,任何安全策略,都可能出现「皇帝的新衣」问题,表面做得好,实际上却不是,呈现出了一种虚假安全感。再举个例子,Timelock 这玩意,看去似乎挺好,实际上出现过有的项目方部署的 Timelock 是有后门的情况。用户一般也不会直接去看 Timelock 源码,而且也不一定看得懂,于是放了个后门在那,一时半会还真不一定有人留意到。
除了权限过大风险,智能合约安全的其他内容也都很关键,但理解门槛还是挺高的,这里就不展开了,我的建议是这样:至少可以逐步学会阅读安全审计报告,熟能生巧。
区块链基础安全
区块链基础安全指的是区块链本身的安全性,如:共识账本安全、虚拟机安全等。如果区块链本身安全性堪忧,其上运行的智能合约项目也可以直接喝西北风了。选择一条拥有足够安全及知名度的区块链,甚至大概率可以源远流长的区块链是多么的重要。
前端安全
前端安全真是魔鬼,与用户走得太近了,特别容易让用户魔怔后上当受骗。可能大家主要的注意力都在自己的钱包上和目标项目的智能合约安全上了,前端安全非常容易被忽视。这里我需要再次强调,前端安全是魔鬼!我重点说说。
前端安全里我最在意的点是:我怎么知道我在这个前端页面里的交互对象就是我以为的智能合约?
造成这种不安全感主要是因为以下这两种风险:
· 内部作恶
· 第三方作恶
内部作恶很好理解,比如开发人员偷偷将前端页面里的目标智能合约地址替换为一个有后门的合约地址,或者直接植入个授权钓鱼脚本。当你访问该前端页面时,你钱包后续的一系列涉及加密货币的操作都可能是在陷阱里完成的。神不知鬼不觉,币没了。
第三方作恶,主要指的是两种:
· 一种是供应链作恶,比如前端依赖的第三方模块被植入了后门,随着打包发布一起被直接带入目标前端页面了。如 SushiSwap(仅仅举例子,并不代表截图里的项目有发生这个问题):
· 一种是前端页面引入的第三方远程 JavaScript 文件,如果这个 JavaScript 文件作恶或被黑,那么目标前端页面可能就会被影响,如 OpenSea(仅仅举例子,并不代表截图里的项目有发生这个问题):
为什么这里说可能会被影响是因为,如果项目方在前端页面以下面这样的方式来引用第三方远程 JavaScript 文件的话,就可能不会被影响:
这里的关键点是 HTML5 的一个不错的安全机制:标签里的 integrity 属性(SRI 机制),integrity 支持 sha256, sha384, sha512,如果第三方 JavaScript 资源不满足 integrity 的哈希完整性校验,就不会加载,这个可以很好防止非预期的代码执行。但使用这个机制需要目标资源支持 CORS 响应。具体参考:
https://developer.mozilla.org/zh-CN/docs/Web/Security/Subresource_Integrity
等等,为什么我前面又提了「可能」,是因为有存在被绕过的场景。至于绕过方式我就不提了,因为大多情况下,你只需关注目标前端页面在引入第三方远程 JavaScript 文件时是否有 integrity 机制。可惜的是,OpenSea 没有,让我们祝福它。
通信安全
通信安全这部分,重点看 HTTPS 安全就好。首先目标网站一定要 HTTPS,绝不允许存在 HTTP 明文传输的情况。因为 HTTP 明文传输实在太容易被中间人劫持攻击了,现在 HTTPS 这种安全传输协议已经非常普遍。如果 HTTPS 出现中间人劫持攻击,比如植入了恶意 JavaScript 代码到目标前端页面,此时浏览器必然会出现 HTTPS 证书错误的高显目提醒。举个例子,曾经 MyEtherWallet 的坑。
MyEtherWallet 曾经是个很流行的网页钱包,现在也挺知名,不过已经不仅仅是网页钱包了。我前面有说过,网页钱包我非常不建议使用,除了前端安全的各种猫腻之外,还可能出现 HTTPS 劫持的风险。
2018.4.24,MyEtherWallet 就出现过 HTTPS 劫持的重大安全事件,回顾可见:
https://www.reddit.com/r/MyEtherWallet/comments/8eloo9/official_statement_regarding_dns_spoofing_of/https://www.reddit.com/r/ethereum/comments/8ek86t/warning_myetherwalletcom_highjacked_on_google/
当时黑客是通过 BGP 这个上古协议劫持了 MyEtherWallet 大量用户所用的 DNS 服务(Google Public DNS),这导致许多用户访问 MyEtherWallet 时,浏览器出现 HTTPS 错误证书的提醒。其实吧,遇到错误证书了,原则上就别继续访问了,因为这表示目标页面已经被劫持了。但是真的许多用户不懂这个安全风险,顶多犹豫下就忽略错误证书的提醒继续强制访问了。
由于目标页面已经被劫持,黑客注入了恶意 JavaScript 代码,直接就盗走了目标用户在目标页面上的明文私钥,之后批量转走这些用户相关的加密货币(主要是 ETH)。
这绝对是个经典案例,黑客为了盗币,动用了 BGP 劫持,真是杀鸡用了牛刀。之后也出现过几起类似的案例,这里就不提了。这里对于用户来说实际上只需要注意一点,当你真的要用网页钱包或玩相关 DApp 时,一定要注意:当目标页面出现 HTTPS 错误证书提醒时,就立即停止继续访问、关闭页面,那么你什么事都不会有。
安全上有个残酷现实,是这样的:当已经出现风险时,就别给用户选择,一旦给了,总会有用户无论出于何种原因会掉坑里。其实这里项目方是需要肩负起相关责任的,比如这个 HTTPS 劫持,其实已经有很好的安全解决方案,项目方的开发人员只需配置好 HSTS 即可。HSTS 全称 HTTP Strict Transport Security,是浏览器支持的一个 Web 安全策略,如果开启了这个配置,浏览器发现 HTTPS 证书错误后就会强制不让用户继续访问。明白什么意思了吧?
人性安全
人性安全这块很好理解,比如项目方内部作恶,这点在前面已经提了些内容,暂时就不过多展开。因为之后,这块还会专门展开讲讲。
金融安全
金融安全是个很需要敬畏的概念,放在 DeFi 上,涉及到金融的点,用户最关心的是币价、年化收益,一定要好,至少要稳。简而言之是,我作为用户,我玩这个 DeFi,我要赚钱。如果亏了,得让我心服口服。嗯,这也是人性。
这部分可能出现诟病的有:
· 不公平启动,比如预挖、老鼠仓。
· 巨鲸攻击,所谓的钞能力。
· 黑庄,看谁跑得快。
· 市场黑天鹅,比如突然的大瀑布,还有如目标 DeFi 与其他 DeFi/Token 套娃或互操作,这个时候木桶短板可能就决定于其他 DeFi/Token 了。
· 还有一些比较技术性的或者说科学家手法,比如抢跑、三明治攻击、闪电贷攻击等。
合规安全
合规安全是个非常大的话题,前面提到的 AML(Anti Money Laundering) 只是其中一点,还有如 KYC(Know Your Customer)、制裁地区限制、证券风险有关的内容等等。其实对于用户来说,这些不是我们可以对抗的,只能说当玩一个项目时,目标项目可能会受到某些国家的安全监管,因此可能会出现我们在意的隐私信息采集的问题。你可能不在意这点隐私,但却有在意的人。
比如,2022 年初出现的一件小事:钱包支持 Address Ownership Proof Protocol(AOPP) 协议。
当时我看了下 AOPP 的协议设计,原来支持了 AOPP 的钱包可能泄露用户隐私:监管机构会有能力知道一个被监管的交易平台和一个不知道的外部钱包之间的关联。参考:
https://gitlab.com/aopp/address-ownership-proof-protocol
怪不得许多隐私钱包重视这个反馈,纷纷删除了这个协议的支持。话说回来:这个协议设计还真有意思。我注意到也有的钱包暂无计划删除对 AOPP 的支持,比如 EdgeWallet,他们的观点认为 AOPP 并没暴露更多的用户隐私,而且可以让加密货币的流转提供更大的帮助,因为,如果用户无法证明一个外部钱包地址属于自己,那么一些被监管的交易平台是不允许用户提币到这个外部钱包地址的。
刚开始知名硬件钱包 Trezor 也是不删除 AOPP 的支持,后来在 Twitter 上迫于社区及用户压力做了删除妥协了。
你看,就这么小的一点,实际上对于有的人来说是隐私大事。这里并不是说要对抗监管,不管合规安全。其实在我的观点里,适当的合规安全妥协是必要的。这个话题就不继续展开说了,按你的舒服的方式去理解就行。
到这,DeFi 安全的主要部分的相关内容就介绍完了。
除了以上这些,还有未来的新增或更改而引入的安全问题,我们经常说「安全是动态的、不是静态的」,指的就是这点。比如现在很多项目方都有安全审计及漂亮的安全审计报告,但如果认真阅读质量不错的报告就会发现,这些报告会说明清楚,什么时间范围安全审计了什么内容,内容的唯一标记是什么(比如链上开源验证后的地址或 GitHub 仓库的 commit 地址,再或者目标代码文件的哈希值)。所以报告是静态的,如果你发现目标项目有不符合报告里的描述内容,就可以指出。
· NFT 安全
前面提的 DeFi 安全几乎内容都可以应用到 NFT 安全上,但 NFT 又有自己独特的安全点,比如:
· Metadata 安全
· 签名安全