WhatsApp, Signal, Telegram 真的是端到端加密的吗?

Updated at: 2024-11-26

我们一步步的来展开这个问题:

第一个问题:葫芦娃和蛇精,需要通过网络进行传递消息,那么消息的路径会是什么样的?

首先在当今基于 TCP/IP 的互联网,葫芦娃和蛇精必须分别有自己的 IP,以接入互联网。但是是网就意味着,葫芦娃或蛇精的消息,可能会经过很多网络节点才能达到对方,中间的网络节点可能是互联网提供商,也可能是 IM 服务提供商。如下图所示:

_

很明显,中间的节点都会看到这个消息,这肯定是葫芦娃和蛇精不期望的。所以他们两个就要考虑将消息加密后再进行传输。那么第二个问题来了。

第二个问题:加密是什么?

所谓加密就是使用一个密钥将消息加密为密文,然后你可以将这个密文通过任何节点来传递都没有问题,只要节点无法获得密钥,也就无法解密密文拿到消息。也就是如下图所示:

_

那么第三个问题来了。

第三个问题:葫芦网和蛇精如何约定这个密钥?

也就是要想在传输之前将消息加密,双方就得约定一个共同的密钥,一方使用此密钥将消息进行加密,然后密文传递过去,另一方获取密文后,使用相同的密钥进行解密,进而得到消息。

问题出在,双方如何约定这个共同的密钥?

目前 Signal 和 WhatsApp 使用 Diffie–Hellman key exchange 算法让葫芦娃和蛇精通过 Signal 和 WhatsApp 的服务器来协商此密钥。注意 DH 算法使用的非对称密钥,这个不是重点,大概流程如下图所示:

_

  1. 葫芦娃先生成一对公私钥
  2. 葫芦娃将自己的公钥通过 Signal 和 WhatsApp 的服务器传递给蛇精。因为暴露公钥没有问题。
  3. 蛇精也生成一对公私钥
  4. 蛇精也将自己的公钥通过 Signal 和 WhatsApp 的服务器传递给葫芦娃。因为暴露公钥没有问题。
  5. 葫芦娃用自己的私钥和蛇精的公钥生成最终要使用的密钥。
  6. 蛇精也用自己的私钥和葫芦娃的公钥生成最终要使用的密钥。
  7. 最终双方得到了一个要使用的密钥。或者基于此密钥衍生密钥。

那么以上有什么问题?在很久以前,我记得使用 mutt(一个终端使用的文本邮件客户端)时,那时搞加密,双方要想安全的传递邮件,必须要通过安全的方式来互相分享双方的公钥,比如线下,因为任何经过第三方来进行公钥或私钥分享的方式都是不可靠的,包括第三方公钥服务器,在以前 Unix Hacker 文化盛行时,甚至大家必须要举行一些线下活动见面来互相分享公钥。

难道 Signal 和 WhatsApp 有什么新魔法来解决这个问题吗?经过研究他们的 paper 和 博客,发现是没有的。如果这个问题不可靠,那么 Signal 和 WhatsApp 中下一步的 X3DH,Double Ratchet Algorithm,前向加密等更复杂概念就都不再可靠。因为经过了 Signal 和 WhatsApp 的服务器这个第三方角色,这个第三方角色可以同时欺骗葫芦娃和蛇精。如下图所示:

_

也就是说,Signal 和 WhatsApp 的服务器可以分别生成两对公私钥,然后分别和葫芦娃和蛇精对接,进而分别生成与葫芦娃的最终密钥和与蛇精的最终密钥。而葫芦娃以为自己的生成的最终密钥是蛇精的,蛇精也以为自己生成的最终密钥是葫芦娃的。那么后续葫芦娃和蛇精通过 Signal 和 WhatsApp 的服务器进行传递加密消息时,Signal 和 WhatsApp 就可以解密传递的消息。

那么 Signal 和 WhatsApp 是如何解决这个问题呢? 解决方案在这里:

也就说你必须通过其他方式,比如线下,来确认你使用的公钥确实是对方的公钥。终究还是必须要回到这个朴素但本质的问题。至于 Telegram 默认服务端则是明文保存消息的,就算是主动开启加密实际也逃不过这个本质的问题。

第四个问题:WhatsApp, Signal, Telegram 是可审计的吗?

可审计的意思是,能否让用户较容易的确认软件的行为确实如他们所说的那样运行的。

WhatsApp 是不开源的;Telegram 是客户端开源,服务端不开源;Signal 是宣称客户端和服务端开源。

显然是否开源已非重点。那么关于可审计,我们应该关注什么?我们应该关注两点:

  1. 一点是软件向软件提供者的服务器上传了什么?重点是上传的数据。
  2. 一点是你应该将软件运行在沙盒环境里,比如 AppStore,浏览器,或者高版本的 Android。这样不但可以限制软件的权限,还可以防止其他软件恶意读取此软件的数据。

关于第一点,我们可以使用网络抓包工具(比如 mitmproxyWireshark) 来观测软件的所有上传数据。

当然,容易观测也就意味着容易破解,所以从某种角度来说可以理解。

纸,一个真正的端到端加密的聊天应用

所以纸诞生了,针对上面提到的问题,纸的解决方案如下:

  1. 关于密钥,纸没有很多复杂的概念,回归本质,使用预共享密钥。即密钥的共享完全由你通过你认为的安全方式的来分享,当然最好为线下。你应该像保护你 BTC 钱包密钥一样来保护你们的聊天密钥,当然你也有责任意识到丢失你们的聊天密钥就和丢失你的 BTC 钱包密钥一样严重。
  2. 所有网络上传接口和数据都是可审计的,并且使用易观测的文本编码格式。并且提供Zhi Upstream API Documentation
  3. 使用随机性的 UUID 代替元数据。
  4. 运行在沙盒环境中。所以你有责任确保你的软硬件环境可信。
  5. 当然任何长期运行的服务,都需要一定的注册成本,来防止恶意用户对服务器资源的滥用。纸不使用手机号,可以使用邮件注册,也可以使用 BTC 获得匿名账号。
  6. Chat 之间互相隔离,即使葫芦娃与蛇精同时在 Chat A 里,也同时在 Chat B 里,葫芦娃和蛇精也无法知道对方与自己同时在两个 Chat 里。

正如 Telegram 创始人所说的,之所以 Telegram 默认不开启端到端加密的原因是为了使用方便,而使用方便才能够更流行。而端到端加密哪里不方便呢?就是无法多端设备无缝同步,因为服务端只有加密数据,而密钥只存在本机设备,要想同步到其他设备,必须得先把密钥弄到其他设备上。那么 WhatsApp 等是如何做的呢?它们使用了苹果的 iCloud 和 Google Drive 来同步,这也是 Telegram 创始人批评它们的一个点。总之,大家只需要记住一点,只要密钥通过第三方传递了,那么可信性就值得怀疑了。而纸采用预共享密钥,你需要自己把密钥放到你的其他设备上,一般为面对面扫码。纸也不会读取通讯录来获取联系人关系,那么就意味着纸只能更为小众。

关于纸的更多细节,请查看博客的其他文章。