Matrix 首页推荐

Matrix 是少数派的写作社区,我们主张分享真实的产品体验,有实用价值的经验与思考。我们会不定期挑选 Matrix 最优质的文章,展示来自用户的最真实的体验和观点。

文章代表作者个人观点,少数派仅对标题和排版略作修改。


多年以前,我还在上大学的时候,曾经听学长说起他打过的一份工,每个月可以赚不少零花钱。这份工作非常简单,就是去互联网上流行的各种网站、手机上流行的各大 APP 以及各个网站的手机浏览器版本(WAP、H5 之类的)执行一些基本的操作,包括注册、登录、操作具体业务等,比如航空类的网站就尝试查询航班、购买机票,团购类的网站就尝试搜索美食、发布评价……

在操作的同时,通过 Wireshark 这样的抓包软件把所有的通信包全部记录下来并分析其中的 HTTP 数据,你会发现账号、业务内容等信息绝大部分都以明文形式在互联网上流动,即使少部分看起来是乱码,经过简单的解码、解密,也可以快速获取原文。

学长告诉我这样的世界太不安全了:想要通过互联网完成任何一件事情,你都需要从电脑或手机发起一系列 HTTP 请求,这些请求通过一层层的路由,最终送到千里之外的某台服务器。

在这个过程中,你同宿舍的室友可能在偷看你的聊天,你的学校也可能以安全为由监控着你的行踪,还有一些不法分子在暗中记录你的账号和密码;在这个过程中,许许多多的钓鱼网站通过拦截你的网络,假冒银行、政府,获取你的信任,套取你的信息;在这个过程中,运营商可能为了利益,在你正常浏览的网页中嵌入了生硬的广告,篡改了原始的页面内容……

直到我们有了 HTTPS —— 它简直就是这一切的「救世主」。

HTTP 带来的风险

HTTPS,中文名是「超文本传输安全协议」(HyperText Transfer Protocol Secure),它以 HTTP 为基础,为 HTTP 提供额外的加密和认证。这也正是其名字的由来:HTTP + Secure。

如果我们用日常生活中的交流来模拟 HTTP,那么 明文的聊天 可能是这样的:

致少数派:我叫李明,我的密码是 123456;我最近收到了什么新的私信?

答复:李明你好,已确认你的身份。昨天张三给你发了一条私信,内容是「天气真好」。

问题在于你和少数派并不是面对面交流的。事实上你跟少数派说的每一句话,都像一张明信片一样,邮局拿到你的明信片,中间经过一层层的邮政网点转发,最终才派送到少数派那儿。少数派给你的答复也是如此。

这样至少就带来以下风险:

  1. 明信片嘛,所有邮递员都可以看到。大家不但知道了你的私信内容,大家甚至知道了你的姓名和密码
  2. 你虽然收到了一个答复,但是你无法确定到底是不是少数派给出的。万一哪个邮递员懒得(或者故意不去)送你的明信片,而自己随便写了一条私信回给你呢?
  3. 内容可能被篡改。邮递员完成了派送,也成功取回了少数派给你的答复。但是少数派回复的私信内容明明是「天气真好」,有个捣蛋的邮递员把它改成了「天气真不好」

HTTPS 的互相问候

引入 HTTPS 之后情况就完全不一样了,虽然仍然使用明信片进行交流,但是这次你和少数派之间首先有个见面的问候:

致少数派:

我需要访问私信;

我懂得使用 TLS_RSA_WITH_AES_256_GCM_SHA384 算法、 TLS_RSA_WITH_AES_128_GCM_SHA256 算法,你选一个;

我生成了一个随机数,11872

当然,实际使用时的信息会再多一些,这里只选取了其中最重要的几个。它们分别是:

  1. 所需访问的网站
  2. 我所支持的算法
  3. 我生成的随机数

少数派拿到你的信息之后,会根据自身情况做出答复:

答复:

我们就用 TLS_RSA_WITH_AES_256_GCM_SHA384 算法吧;

我也生成了一个随机数,785391;

给你私信网站的证书(一个文件袋)

少数派给的答复也比我所举的例子复杂得多,这里选取的几项分别是:

  1. 从你所给的几种算法中挑了一种,双方都合适的
  2. 也生成了一个随机数
  3. 给了你所需网站的证书

HTTPS 的安全通道尚未建立,但是我们有必要先来看一下这张证书。

证书,一个文件袋

经过和少数派的第一次通信,你拥有了一张证书;或者说是一个文件袋,里面装满了各种文件,可供查验和使用。你可以在任何浏览器中看到这张证书。

例如使用 Google Chrome 打开少数派网站,地址栏的左侧会出现一把小锁。点击之后,可以查看证书的详细情况:

这张证书主要包含以下信息:

  1. 证书颁给了哪个或哪些网站(使用者)
  2. 证书的有效期的起止时间(有效期)
  3. 一个公钥
  4. 证书是由谁颁发的(颁发者)

接下来,你会一一对这些信息进行处理。

第一项很好理解,使用者,就是这张证书对谁有效。你看了一眼,嗯,*.sspai.com,这是一个通配符域名,意思就是对所有 sspai.com 的域名都有效。好的,它确实符合少数派网站的网址,验证通过。

第二项,有效期,也很容易。你在自己的电脑上查了一下时间,2021 年 8 月,确实是在有效期区间内,好的,验证通过。

第三项是一个 公钥,先存下来后面用。

第四项,颁发者,虽然你知道了这张证书是由一个叫做 RapidSSL TLS DV RSA Mixed SHA256 2020 CA-1 的人颁发的。但这个人又是谁,他值得信任吗?

这就要看证书中的最后一项内容,证书路径。在这里,我们可以通过一个树形图,清晰地看到我们当前这个证书的信任链。对于列表中的每一项,都可以通过右下方「查看证书」按钮,读取到这一项的证书信息。

也就是说,列表中的每一项其实都是一张完整的证书。在这个例子中:

  • RapidSSL TLS DV RSA Mixed SHA256 2020 CA-1 保证了 *.sspai.com 的证书是可信任的
  • DigiCert 保证了 RapidSSL TLS DV RSA Mixed SHA256 2020 CA-1 的证书是可信任的
  • 浏览器,或者操作系统,充分信任 DigiCert(浏览器或操作系统会维护一个受信任的列表)

因此,随着一层层的信任关系你也就信任了 *.sspai.com 这张证书;这种信任带来的最重要的意义在于——你相信,证书中包含的那个「公钥」确实是属于少数派的,而不是其中任何一个邮差伪造的。

所以,证书带来的结果就是:你拥有了一个确信是少数派的公钥

HTTPS 的初次加密尝试

公钥就像是从证书这个文件袋中捎过来的一个信封,一旦封口,就只有证书拥有者使用私钥才可以打开;换言之,你只要用这个信封寄送,那么就只有少数派可以读到(啊,用于封口的是 一种神奇的胶水,这是由数学原理保证的)。

你可以放心地使用从证书中找到的这枚公钥。如果你决定试一下,便可以生成一个随机数 36721,写在明信片上,然后兴致勃勃地把明信片装进信封,仔细地封好口子。

【这是只有你和少数派才可以看到的内容】

现在,你交给邮局的不再是体无遮拦的明信片,而是一个信封。邮差看不到信件的内容,他只知道这封信送往何处;少数派成功收到了这封信,并使用少数派的私钥拆开了信封。最后一个随机数成功送达。

整理一下。结合前面的「问候」过程,现在你和少数派双方手上拥有:

  1. 一个双方都认可的加密算法 TLS_RSA_WITH_AES_256_GCM_SHA384,邮差可以偷看
  2. 一个少数派生成的随机数 785391,邮差可以偷看
  3. 一个你生成的随机数 11872,邮差可以偷看
  4. 另一个你生成的随机数 36721,只有你和少数派知道

通过这些信息,你和少数派会各自使用三个随机数和算法,计算出一个称为「会话密钥」的密码。由于随机数和算法都已经确定,因此你和少数派计算出的「会话密钥」必然是一致的;假设这个计算出来的密码是 1627638。

你们事实上完成了一件很有意思的事情:在所有聊天内容都会被人偷看的情况下,你们成功交换了密码。这使得后续的秘密聊天成为可能。交换密钥的方法也还有很多,这里仅仅展示了其中的一种。

愉快的秘密通信

好了,最后,你们可以使用前面制作的 1627638 这个密码来进行后面的聊天。

这个密码用起来就方便多了,只要双方通过 一个带密码锁的小盒子 来互相通信,那路上的邮差就肯定打不开。

暴力解锁?密码复杂度保证了即使用人类最顶级的计算机,也无法在有生之年把密码猜出来。(1627638 这只是个例子,实际使用当然不可能这么短小)

你把想问的问题(我的私信?)塞进了密码锁,并把密码锁的密码设为 1627638,锁上之后打乱密码锁。

少数派拿到了这个密码锁,通过 1627638 解开密码锁。同样的,少数派会把你的私信内容也用 1627638 锁上,寄回给你。

最后,你还是用 1627638 解锁私信内容,秘密通信顺利完成。

再来回头看看最开始 HTTP 遇到几个风险,在 HTTPS 中是如何解决的:

  1. 邮差知道了你的私信内容、姓名和密码:在 HTTPS 中,由于通信使用 1627638 这个密码锁来加密,所以路上的邮差不可能知道信件的内容
  2. 无法确定到底是不是少数派给出的答复:在 HTTPS 中,证书的信任链保证了「公钥」的可信度,而公钥和私钥的匹配认证了少数派的身份
  3. 捣蛋的邮递员修改了信件内容:在 HTTPS 中,由于使用了密码锁,邮差读不了邮件,也无法写入信件

所以通过这稍显复杂的 HTTPS 通道,我们最终解决了 HTTP 的一些风险。

HTTPS 已随处可见

现在几乎所有主流的浏览器都已经用比较强烈的视觉效果区分了 HTTP 和 HTTPS 网站,例如 Google Chrome,访问少数派网站时,地址栏前方的标识是一把寓示着安全的小锁,点开则提示「连接是安全的」:

而如果访问一个使用 HTTP 的网站,则会直接显示「不安全」:

当访问的网站,虽然正常完成了「问候」的过程,但是从服务器取到的证书存在或多或少的问题时,浏览器会阻断你们之间的通信:

即使通过「高级」按钮底下的选项坚持访问,浏览器依然会时刻把「不安全」标注为醒目的红色:

这样激进的措施曾经饱受争议,但是浏览器这样的强制性的行为却带来了非常好的结果。时至今天,我们已经很少见到有哪个网站还只支持 HTTP 访问,也很少见到证书错误的情况。以至于当我们说起互联网的时候,我们已经很难想象,当年那样几乎完全基于 HTTP 的通信是多么不可靠、不安全。

还有几个问题值得讨论

为什么一定要有「会话密钥」,直接使用公私钥对来通信不好吗?

确实,为了交换一个保险箱密码我们多花了不少精力。而要取得少数派的神奇信封,似乎只要向少数派索取一个证书就可以了。

但这样做原因很简单:用保险箱上锁,只要打乱密码就可以了,成本低;而神奇信封和用于封口的神奇胶水太贵了。

术语来讲,前者称为对称加密,后者称为非对称加密。对称加密更加高效。

为什么有些软件还是可以读取 HTTPS 内容?

我所知的几种方法。

第一种,你可以直接通过浏览器 F12 的「网络」标签页来读取 HTTPS 内容。这里,浏览器就是通信双方中的一方(也就是上文中的「你」),自然知道所有的加密要素,所以通过浏览器可以读到明文的数据也就不足为奇了;就像你可以知道你发给少数派、少数派发给你的所有信息一样自然。

第二种,你信任其中一个邮差,告诉了他密码锁的密码;那邮差就可以读信给你听了。

还有一种,是通过安装私有证书来实现。你信任一个邮差,所以你把邮差的证书加入了自己系统的「受信任列表」;于是:

  1. 你跟邮差之间通信,使用邮差的证书
  2. 邮差收到你的内容,转发给少数派,使用少数派的证书
  3. 邮差收到少数派的内容,用少数派的密码解密
  4. 邮差把少数派的答复转发给你,用与你之间的密码加密

所以,只要你保护好自己的「受信任列表」,就不用担心 HTTPS 通信被他人偷看,换句话说,如果有网站让你「添加证书到系统」,为了安全请一定要慎重

自签名证书安全吗?

不安全,自签名证书属于自欺欺人、掩耳盗铃、欲盖弥彰。

有些网站会自己签发证书。由于缺少了可靠的证书信任链,客户端无法验证服务端的真实身份,因此信件很容易被路上的邮差调包;如果邮差从最开始的「问候」阶段就开始动坏心思,那么整个通信都可以被邮差控制。

当使用自签名证书时,几乎所有浏览器都会给出证书出错的提示,需要用户手动确认才可以继续访问。

中间人还可以窃听到什么信息?

路由器和运营商提供的访问统计、以安全之名实行的网站拦截,亦或是以大数据之名而进行的隐私追踪,这些在 HTTPS 中依然可以做到吗?采取了 HTTPS 通信后,作为路上的邮差,还可以偷看到哪些信息呢?

自然,加密信件的全部内容都无法获取。这些内容包括:

GET /message/2hzb91qd HTTP/1.1
Host: sspai.com
Connection: keep-alive
Cache-Control: max-age=0
sec-ch-ua: "Chromium";v="92", " Not A;Brand";v="99", "Microsoft Edge";v="92"
sec-ch-ua-mobile: ?0
DNT: 1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36 Edg/92.0.902.62
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6,zh-TW;q=0.5,ja;q=0.4,sl;q=0.3
If-Modified-Since: Wed, 04 Aug 2021 08:54:52 GMT

HTTP/1.1 200 OK
Server: nginx/1.10.3
Date: Wed, 04 Aug 2021 08:55:22 GMT
Last-Modified: Wed, 04 Aug 2021 08:54:52 GMT
Access-Control-Allow-Origin: *.sspai.com
Content-Type: text/html
Vary: Accept-Encoding
ETag: W/"610a55dc-1121"
Content-Encoding: gzip

<!DOCTYPE html><html lang=en id=html>
...

也就是说,包括主机名、请求体、URL路径和参数、返回的头部和消息体,这些都是加密的。而信件的地址,也就是 IP 地址,必然是会被邮差知道,否则邮差不知道把信送到哪儿去。

唯一的漏网之鱼来自于 SNI(Server Name Indication,服务器名称指示)。客户端向服务端发起请求的时候,会表明自己想要访问的网站。例如,前面的例子中,你向少数派问候时:

我需要访问私信

而少数派则回复:

给你私信网站的证书(一个文件袋)

这是因为,同一台服务器上,可能部署了多个子网站(例如可能私信、文章区分了不同的子域名,但是部署在同一个服务器上),那么就需要客户端指明所需访问的网站,服务器才可以给出合适的证书。

例如,sspai.com 或者 ditu.baidu.com 这样的域名依然通过「明信片」的形式发送,邮差们可以随意查看。但是, /message/2hzb91qd 这样表明「查看某条私信」的具体操作,则是安全的。

这也为基于 HTTPS 的网络通信过滤提供了方便。前面所说的访问统计、网站拦截、隐私追踪,很大一部分都是靠的 SNI 这个参数。但是就像前述例子中所述,SNI 仅提供域名,而 URL 地址包含在加密的 HTTP 消息中,因此追踪也相对有限。

事实上,现在也有技术来保护 SNI 的安全,例如 ESNI 和后来演变成的 ECH 都是非常有效的尝试。

你可以做些什么

基于前面的讨论,我们可以思考如何更安全地在互联网上浏览。

从一开始就使用 HTTPS

对于支持 HTTPS 的网站,大部分都对 HTTP 进行了跳转。举例来说,当你访问少数派网站时,如果直接在浏览器中输入 sspai.com 就敲下回车键,那么浏览器会自动跳转到 http://sspai.com 而不是 HTTPS 站点。而少数派网站在收到 HTTP 请求后,会告诉你:我改地址了,请使用 HTTPS 访问。

致少数派:我需要访问首页,这是我的个人信息

答复:我换地方了,请使用 https://sspai.com/ 重新访问

于是,你重新发起了一次聊天,这次,你使用了 HTTPS。

这里有很明显的问题,当你使用 HTTP 访问时,你已经把你需要访问的内容(少数派首页)、你的个人信息,都以「明信片」的形式交给了邮差。虽然少数派提醒了你需要更换地址并拒绝给予任何有实际意义的答复,但是这之前已经稍许泄露了信息。

所以最好的做法是,当你访问网站时,直接输入: https://sspai.com 而不要偷懒让浏览器自动去跳转。

绝对不要信任不可靠的证书

这些行为包括:

  • 有些银行网站,会让你提前安装「网银助手」,其中一步就是「把银行自己的证书安装到系统中」。这其实并不安全。不过现在这样做的银行已经越来越少了。
  • 遇到证书过期、域名不匹配、信任链存在瑕疵的证书时,浏览器会给予全屏提示。此时虽然有小字可以点击「继续访问」,但是非常不推荐此时继续输入敏感信息。

为自己的网站加上 HTTPS

如果你拥有自己的个人网站或者博客,那么你一定要配置一下 HTTPS 证书。我经常使用 Let's Encrypt 提供的免费证书,借助 Certbot 这个一键配置工具,简单几行命令就可以一劳永逸地配置完成。

Let's Encrypt 的证书有效期只有三个月,但是 Certbot 提供了自动续期的功能,有效期将近时会自动更新服务器上所有托管的证书。

> 下载少数派 客户端 、关注 少数派公众号 ,了解更妙的数字生活 🍃

> 想申请成为少数派作者?冲!