本文首发于 ❄️慕雪的寒舍

链滴(思源笔记社区)里面有不少老哥似乎不太了解思源使用的端到端加密功能,以及云同步功能背后的机制。本文将以思源笔记为例,谈谈什么是端到端加密,以及思源的同步功能中用到了什么计算机网络相关的技术。

1. 思源笔记如何进行跨设备同步?

下面这张图比较直观的展示了思源笔记客户端是如何进行云端同步的。

image.png

这里假设设备A是第一个使用思源笔记的客户端,设备B是需要从设备A同步数据的客户端。举个栗子:设备A是一台电脑,用户在上面编辑笔记,且希望在自己的手机(设备B)上能访问、阅读自己的笔记。是非常常见的笔记软件使用场景。

为了让大家有个更清晰的认识,我们一步一步谈起,力求让不是程序员的朋友也能简单了解一下这个同步机制是怎么运作的。

2. AES加密

在描述思源采用的加密算法之前,先和大家明确一下加密、解密的概念:

  • 加密:通过一系列操作,将能被直接阅读的数据,加密成不可阅读的数据;
  • 解密:通过一系列操作,从不可阅读的加密数据中,解密还原出原本的可读数据;
  • 加密后的数据被称为密文,能被直接阅读的数据被称为明文。

你可以百度一个在线AES加密网站来试试加密和解密,如下图所示,我使用了一个随机的密钥对“你好”进行加密,得到的结果是Oru2UtIlrV+qpmKudjZAxQ==这串不知道是什么鬼的密文数据。这便是加密的作用。

image.png

解密就是通过相同的密钥,将Oru2UtIlrV+qpmKudjZAxQ==这个鬼东西还原出“你好”的过程。


思源笔记在启用云端同步之前,都会配置一个密钥。这个密钥是用于AES加密的,AES是目前广泛使用的一个加密算法,他是用于替代现在已不再可靠的DES加密算法的。

在AES加密算法没有被攻破之前,想解密被AES加密后的内容,只有一种方式,那便是暴力穷举加密时使用的密钥。

在《网络安全基础:应用与标准(白国强 译)》的AES章节中,会有下面这一张图,是穷举密钥需要用的时间。当使用128位(16字节,也就是长度为16的字符串)的密钥作为AES加密的输入时,就已经需要10^17年这个量级才能完成解密的,已经远远大于了这个数据有意义的时间了。

image.png

你想想,你今天偷到了一个机密资料,结果发现解密这个机密资料需要的时间,比地球他老人家的年龄都大,甚至比宇宙大爆炸到现在的时间都长,哪还有解密的必要?等暴力破解出来,这个资料早就没有参考价值了。这便是当下密码学算法希望达成的一个目标,即算法理论上能被暴力穷举破解出密钥,但穷举的耗时和成本(运算解密程序需要算力、电费、人力维护等等)会让做这件事毫无意义。

关于这一点,在暴力解决一切?破解AES也是妄想!一文中有更详细的解释,本文不再拓展。

3. HTTPS和TLS Verify

可能有老哥就想问了,既然AES加密算法那么牛逼,为啥只有思源笔记在云同步功能里面加上了这个东西,其他软件会使用AES加密吗?

当然也会了!现在互联网通信中最重要的也是最最常用的协议之一:HTTPS,背后就用到了TLS和AES加密。现在几乎所有APP、网站,背后都多少会用到HTTPS或者TLS来保障数据传输时的机密性。

当你访问一个HTTPS的网站时,以https://www.baidu.com/为例,TLS握手协议能保障你现在访问的服务器肯定是百度官方的服务器,而不是某个坏蛋设置的假冒服务器。TLS握手协议完成后,你的浏览器就会和百度的服务器协定一个共享密钥,并使用AES对称加密进行数据通信。最后在网络中流动的实际数据,比如你查询的一个关键词的结果,也已经是加密后的内容了。

这整个过程都是浏览器或者应用软件自行处理的,并不需要用户做额外的配置。

HTTPS中会使用到的一个东西叫做SSL/TLS证书,这是由可信CA颁发的用于验证服务器身份和进行密钥交换的必要组件,HTTPS可以避免中间人攻击正是靠证书实现的。如果你使用过nginx,或宝塔这类服务器管理面板,里面配置HTTPS部分一定会有一个证书的配置项。由于这部分的知识比较深奥,涉及环节较多,不太好对小白解释,本文跳过此知识点。

细心的朋友可能会发现,在思源的云端配置中,也是有TLS Verify这个选项的,它的作用就是和提供S3/WEBDAV服务的目标服务器进行身份验证。

image.png

TLS Verify在这里和Endpoint使用的HTTPS协议是绑定的。如果你使用了一个HTTP的Endpoint,即便开启TLS Verify也是没有意义的,因为HTTP协议是不包含TLS握手环节的。不过,现在很多服务器都会强制将HTTP的协议流量重定向到HTTPS。除非你本地不支持HTTPS和TLS协议,否则最终都会走HTTPS协议进行数据通信。

也就是说,如果你使用了一个HTTPS协议的Endpoint,也开启了TLS Verify,最终思源笔记和S3存储商之间的数据传输,其实是经过了两层加密的,一层是思源笔记本身配置的数据库加密密钥,另外一层是本地和S3/WEBDAV服务器通信时使用的HTTPS协议。

如果某一个服务器使用的是自签名的证书来进行HTTPS传输,此时TLS Verify肯定会失败,因为服务器使用的证书并不是可信CA颁布的,当前主机认为这个证书不值得信任,在TLS握手的证书验证环节中会失败,从而拒绝连接。此时您可以把TLS Verify选项关闭,使用HTTP协议或者不可信的HTTPS协议继续传输数据,但我不建议这么做。虽然思源笔记本身数据就会有一层加密,但最终你和服务器之间的通信可能会被中间人窃取,从而获取到你使用的S3协议用户密钥等等信息,即便对方没有办法解密你的笔记内容,但是他人可以使用你的S3用户密钥去访问你使用的S3服务,从而获取到你的其他未加密信息。

不过,如果您是在局域网内使用nas上自建的minio、webdav服务,此时就不需要考虑HTTPS了,可以直接使用HTTP。除非您的局域网内有可以联网的设备被入侵了,才有可能被中间人攻击。当然,如果您的nas使用了ddns之类的方式暴露在公网上了,那就和上文所述的情况一致,得考虑中间人攻击问题了。

4. 同步到云端,从云端同步

现在我们已经知道了AES加密和HTTPS协议是怎么保障我们数据通信的机密性了,下面给大家阐述一下思源从设备A将数据同步到设备B会做的全流程操作。

  1. 用户在设备A按下同步按钮,思源开始处理本地数据库数据,和云端已有数据进行对比,找出云端不存在的数据。
  2. 设备A的思源将这部分只有本地存在的数据使用配置好的数据库密钥K进行加密,并通过配置的S3/WEBDAV协议上传至云端。这个过程中会涉及上文所述的HTTPS和TLS,但都是思源笔记客户端依照协议特性自动完成了所有操作,和用户配置的密钥K没有什么关系。
  3. 数据上传完毕,思源会校验云端数据是否和本地一致,以确认同步是否成功。
  4. 云端S3/WEBDAV存储服务商存储的是已经加密过的用户笔记数据。
  5. 用户在设备B按下同步按钮,思源开始处理本地数据库数据,和云端已有数据进行对比,发现云端数据更新,存在云端有而本地没有的数据,并将这部分本地不存在的数据找出来。
  6. 设备B的思源从云端下载数据,并使用数据库密钥K对数据进行解密,还原出笔记内容。
  7. 下载完毕后,再次检查本地和云端数据快照,确认同步完成。

其实思源笔记不能实时多设备同步的原因从这个流程就能看得出来。

  • 假设用户在设备A上写了新文档甲和新文档乙,按下同步按钮,设备A执行上传操作;
  • 用户又在设备B按同步按钮,设备B执行下载操作;
  • 此时就出现了两台设备都在访问云端仓库,而云端仓库中的数据还在不断的被A更新;
  • 这就出现问题了!到时候B下载的数据要么是缺胳膊断腿的,要么是因为损坏无法被正常解密的无效数据,比如文档甲只下了一半的加密内容下来;
  • 假设用户没有发现这个问题,有一天设备A上的某某文件丢失或者被误删了,用户打算从设备B上把数据全量同步到云,此时就会把设备B上可能存在损坏的文档甲和乙同步到云,从而导致文档甲和乙的数据丢失!

所以,思源笔记使用的同步流程,就决定了它不能实现完全实时的同步,也不能在多台设备上同时操作同步。如果没记错的话,思源在同步之前会去锁定云端目录,保证同一时间只有同一个设备在上传/下载云端数据,来避免另外一台设备触发同步操作而导致的数据一致性问题。

The end

那flowus、语雀是怎么实现在线编辑、实时同步和多用户协作编辑的呢?这就涉及到编程中多线程里面会涉及到的一个锁机制:乐观锁。

不过这部分内容对于非程序员来说恐怕比HTTPS证书是怎么保证数据不被中间人窃取解释起来还要费劲,就不提啦!

看完本文,不知道你对思源笔记的端到端加密同步功能是否有了一个更清晰的认识呢?如果文章有什么描述你没有看懂,或者大佬发现我的表述有误,都可以在评论区提出来。感谢大家的阅读!