WhatsApp, Signal, Telegram 真的是端到端加密的吗?
Updated at: 2024-11-26
我们一步步的来展开这个问题:
第一个问题:葫芦娃和蛇精,需要通过网络进行传递消息,那么消息的路径会是什么样的?
首先在当今基于 TCP/IP 的互联网,葫芦娃和蛇精必须分别有自己的 IP,以接入互联网。但是是网就意味着,葫芦娃或蛇精的消息,可能会经过很多网络节点才能达到对方,中间的网络节点可能是互联网提供商,也可能是 IM 服务提供商。如下图所示:
很明显,中间的节点都会看到这个消息,这肯定是葫芦娃和蛇精不期望的。所以他们两个就要考虑将消息加密后再进行传输。那么第二个问题来了。
第二个问题:加密是什么?
所谓加密就是使用一个密钥将消息加密为密文,然后你可以将这个密文通过任何节点来传递都没有问题,只要节点无法获得密钥,也就无法解密密文拿到消息。也就是如下图所示:
那么第三个问题来了。
第三个问题:葫芦网和蛇精如何约定这个密钥?
也就是要想在传输之前将消息加密,双方就得约定一个共同的密钥,一方使用此密钥将消息进行加密,然后密文传递过去,另一方获取密文后,使用相同的密钥进行解密,进而得到消息。
问题出在,双方如何约定这个共同的密钥?
目前 Signal 和 WhatsApp 使用 Diffie–Hellman key exchange 算法让葫芦娃和蛇精通过 Signal 和 WhatsApp 的服务器来协商此密钥。注意 DH 算法使用的非对称密钥,这个不是重点,大概流程如下图所示:
- 葫芦娃先生成一对公私钥
- 葫芦娃将自己的公钥通过 Signal 和 WhatsApp 的服务器传递给蛇精。因为暴露公钥没有问题。
- 蛇精也生成一对公私钥
- 蛇精也将自己的公钥通过 Signal 和 WhatsApp 的服务器传递给葫芦娃。因为暴露公钥没有问题。
- 葫芦娃用自己的私钥和蛇精的公钥生成最终要使用的密钥。
- 蛇精也用自己的私钥和葫芦娃的公钥生成最终要使用的密钥。
- 最终双方得到了一个要使用的密钥。或者基于此密钥衍生密钥。
那么以上有什么问题?在很久以前,我记得使用 mutt(一个终端使用的文本邮件客户端)时,那时搞加密,双方要想安全的传递邮件,必须要通过安全的方式来互相分享双方的公钥,比如线下,因为任何经过第三方来进行公钥或私钥分享的方式都是不可靠的,包括第三方公钥服务器,在以前 Unix Hacker 文化盛行时,甚至大家必须要举行一些线下活动见面来互相分享公钥。
难道 Signal 和 WhatsApp 有什么新魔法来解决这个问题吗?经过研究他们的 paper 和 博客,发现是没有的。如果这个问题不可靠,那么 Signal 和 WhatsApp 中下一步的 X3DH,Double Ratchet Algorithm,前向加密等更复杂概念就都不再可靠。因为经过了 Signal 和 WhatsApp 的服务器这个第三方角色,这个第三方角色可以同时欺骗葫芦娃和蛇精。如下图所示:
也就是说,Signal 和 WhatsApp 的服务器可以分别生成两对公私钥,然后分别和葫芦娃和蛇精对接,进而分别生成与葫芦娃的最终密钥和与蛇精的最终密钥。而葫芦娃以为自己的生成的最终密钥是蛇精的,蛇精也以为自己生成的最终密钥是葫芦娃的。那么后续葫芦娃和蛇精通过 Signal 和 WhatsApp 的服务器进行传递加密消息时,Signal 和 WhatsApp 就可以解密传递的消息。
那么 Signal 和 WhatsApp 是如何解决这个问题呢? 解决方案在这里:
- https://signal.org/blog/safety-number-updates/
- https://support.signal.org/hc/en-us/articles/6829998083994-Phone-Number-Privacy-and-Usernames-Deeper-Dive
也就说你必须通过其他方式,比如线下,来确认你使用的公钥确实是对方的公钥。终究还是必须要回到这个朴素但本质的问题。至于 Telegram 默认服务端则是明文保存消息的,就算是主动开启加密实际也逃不过这个本质的问题。
第四个问题:WhatsApp, Signal, Telegram 是可审计的吗?
可审计的意思是,能否让用户较容易的确认软件的行为确实如他们所说的那样运行的。
WhatsApp 是不开源的;Telegram 是客户端开源,服务端不开源;Signal 是宣称客户端和服务端开源。
- 那么有一个问题是:我们有没有办法证明 Apple AppStore 上下载的就是 100% 由开源代码构建的?
- 答案是没有。
- 另一个问题是:我们有没有能力来审计每一行代码,尤其是一个软件又递归式的依赖的代码?
- 答案也是没有,比如最近的 XZ Utils 恶意代码。
显然是否开源已非重点。那么关于可审计,我们应该关注什么?我们应该关注两点:
- 一点是软件向软件提供者的服务器上传了什么?重点是上传的数据。
- 一点是你应该将软件运行在沙盒环境里,比如 AppStore,浏览器,或者高版本的 Android。这样不但可以限制软件的权限,还可以防止其他软件恶意读取此软件的数据。
关于第一点,我们可以使用网络抓包工具(比如 mitmproxy 或 Wireshark) 来观测软件的所有上传数据。
- 那么我们可以观测 WhatsApp, Signal, Telegram 的网络上传数据吗?
- 经过我的测试,不排除天外有高人,不说绝对不能,我的答案是非常难。
当然,容易观测也就意味着容易破解,所以从某种角度来说可以理解。
纸,一个真正的端到端加密的聊天应用
所以纸诞生了,针对上面提到的问题,纸的解决方案如下:
- 关于密钥,纸没有很多复杂的概念,回归本质,使用预共享密钥。即密钥的共享完全由你通过你认为的安全方式的来分享,当然最好为线下。你应该像保护你 BTC 钱包密钥一样来保护你们的聊天密钥,当然你也有责任意识到丢失你们的聊天密钥就和丢失你的 BTC 钱包密钥一样严重。
- 所有网络上传接口和数据都是可审计的,并且使用易观测的文本编码格式。并且提供Zhi Upstream API Documentation。
- 使用随机性的 UUID 代替元数据。
- 运行在沙盒环境中。所以你有责任确保你的软硬件环境可信。
- 当然任何长期运行的服务,都需要一定的注册成本,来防止恶意用户对服务器资源的滥用。纸不使用手机号,可以使用邮件注册,也可以使用 BTC 获得匿名账号。
- Chat 之间互相隔离,即使葫芦娃与蛇精同时在 Chat A 里,也同时在 Chat B 里,葫芦娃和蛇精也无法知道对方与自己同时在两个 Chat 里。
正如 Telegram 创始人所说的,之所以 Telegram 默认不开启端到端加密的原因是为了使用方便,而使用方便才能够更流行。而端到端加密哪里不方便呢?就是无法多端设备无缝同步,因为服务端只有加密数据,而密钥只存在本机设备,要想同步到其他设备,必须得先把密钥弄到其他设备上。那么 WhatsApp 等是如何做的呢?它们使用了苹果的 iCloud 和 Google Drive 来同步,这也是 Telegram 创始人批评它们的一个点。总之,大家只需要记住一点,只要密钥通过第三方传递了,那么可信性就值得怀疑了。而纸采用预共享密钥,你需要自己把密钥放到你的其他设备上,一般为面对面扫码。纸也不会读取通讯录来获取联系人关系,那么就意味着纸只能更为小众。
关于纸的更多细节,请查看博客的其他文章。