网络知识

为什么浏览器会提示网站链接不安全?

大家在日常使用浏览器的时候,是否有留意到有一些网站会提示你:『与此网站之间建立的链接不安全』等类似地警告呢?

从这个现象出发,让我们思考几个问题。为什么浏览器会认为你访问这个网站的链接不安全呢?怎样才能使自己访问网站的链接变得安全?

再联系一下现实的一个场景。当我们访问网络的时候,网线都是从电信运营商拉的,这个过程势必要经过运营商的机器。那是不是意味着我们访问的一切内容在运营商面前都是透明的?当我使用浏览器的网银进行转账的时候,运营商的工作人员是不是有办法看到我们访问网银时的密码,甚至来盗取我们的银行账户呢?当我们访问一些敏感网站时,运营商是否会知晓我们访问的内容呢?

http 和 https 在许多网站都有用到,但是现在都是极力倡导使用 https ,究其原因就是 http 的安全性不够高,在数据传输过程中可能会遭到黑客窃取。

通信使用明文(不加密),内容可能会被窃听
http (HyperText Transfer Protocol),即超文本运输协议,是实现网络通信的一种规范。
1)http 本身不具备加密的功能,因此其在通信过程是使用明文方式发送的。这种方式就有可能造成通信过程中信息会被破解获取。
例如:一群佩奇在路上坐着敞篷大货车,路过的人直接能看到车里都是佩奇,信息完全暴露。不验证通信方的身份,有可能遭遇伪装。

2)http 协议在请求和响应中不会对通信方进行确认。这就存在你访问的服务器有可能不是你真正指定的服务器,拿到返回响应的客户端可能不是一开始发起请求的客户端。
例如:母鸡孵蛋,我偷偷把鸡蛋换成鸭蛋,母鸡照样在那孵,不会有任何的怀疑。无法证明报文完整性,有可能信息已遭篡改。

3)http 协议无法证明通信的报文完整性,在请求和响应发出后,在传输过程中内容如果遭到篡改,也没有办法感知到。
例如:你从某个网站下载内容,无法确定你客户端下载的文件和服务器中存放的文件是否一致,有可能文件在传输过程中被篡改为其他的内容。

HTTP协议的起源


HTTP协议,全称超文本传输协议(英语:HyperText Transfer Protocol,缩写:HTTP)。该协议是由英国的伯纳斯·李博士于1989年发起,随后由万维网协会(World Wide Web Consortium,W3C)和互联网工程任务组(Internet Engineering Task Force,IETF)制定并维护相关的标准。1990年,伯纳斯·李成功利用互联网实现了超文本传输协议客户端与服务端的第一次通讯。而他本人也因”发明了万维网、第一个浏览器和使得万维网得以扩展的基础协议及算法”而获得2016年度的图灵奖。该项奖项被认为是计算机界的诺贝尔奖。

HTTP协议是一个客户端(浏览器)和服务端(网站)之间请求和应答的标准,几乎所有的浏览器和网站都会予以支持,并以此来提供服务。HTTP协议是全球互联网资讯传输,尤其是网站访问的一个重要基础。在移动互联网时代,不仅仅浏览器,在各种APP的开发中,也广泛使用了HTTP协议来从服务器获取信息。

当我们从浏览器复制一个链接出来时,时常会发现其是以http这几个字母开头的,这便是使用HTTP协议传输的标识。(尤其是那些浏览器提示你不安全的链接。更多的链接复制出来的可能是https开头的,其中区别,我们会在下文讲解)

HTTP 协议是一种基于文本的传输协议,它位于 OSI 网络模型中的应用层。

HTTP 协议是通过客户端和服务器的请求应答来进行通讯,目前协议由之前的 RFC 2616 拆分成立六个单独的协议说明(RFC 7230、RFC 7231、RFC 7232、RFC 7233、RFC 7234、RFC 7235),通讯报文如下:

请求:

POST http://www.baidu.com HTTP/1.1  
Host: www.baidu.com  
Connection: keep-alive  
Content-Length: 7  
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36  
  
wd=HTTP  

响应:

HTTP/1.1 200 OK  
Connection: Keep-Alive  
Content-Encoding: gzip  
Content-Type: text/html;charset=utf-8  
Date: Thu, 14 Feb 2019 07:23:49 GMT  
Transfer-Encoding: chunked  
  
<html>...</html>  

大家可以发现,目前基本上需要用户输入数据的网站都是使用https协议,简单来说就是比http更安全,使用了更高级的加密方式,即使部分网站使用http协议,用户输入数据也会使用哈希函数或者其他加密方式,http协议为什么不安全呢?我们不妨亲自抓包感受一下,自己输入的账号密码可以直接被获取!

HTTP协议的缺陷


HTTP协议最大的缺陷是明文传输,也就是你通过HTTP协议访问的内容,在链路中的任何中介,都可以查看到明文内容,比如运营商。这种在信息传输链路中间,拦截、获取甚至篡改内容的攻击被称为中间人攻击。

HTTP明文传输的问题给它的应用带来了很大的阻碍。一些安全要求较高的场景,比如网银转账,敏感文件传输等,必然不能安心地使用HTTP协议传输。即便是普通场景的访问,试想一下,整条网线随便找个地方掐断,接上一台设备就能查看你访问的内容,听起来也是毛骨悚然的。

现在我们可以部分回答本文最初的问题了。为什么浏览器会提示你访问这个网站的链接不安全呢?一种可能就是你正在使用HTTP协议访问网站的内容。浏览器认为你使用明文的HTTP协议访问内容时,内容有较大地被泄露和篡改的风险,因此做出提示。复制一下那些被提示访问链接不安全的网址出来,你会发现他们大多以http开头。

可能会有一些读者在操作的过程中发现,很多网站的链接,尤其是被浏览器识别为安全的那些链接,往往是以https开头。https代表在着什么呢?这是HTTPS传输协议的标识。HTTPS协议,全称是超文本传输安全协议(英语:HyperText Transfer Protocol Secure,缩写:HTTPS)。顾名思义,HTTPS协议在HTTP协议的基础之上,解决了明文传输的缺陷,成为了一种安全的协议。所以大多数情况下,浏览器会将https开头的链接,标记为链接是安全的。

但是在极少数的情况下,还是有可能遇到使用的是https开头的链接,却被浏览器提示了链接不安全的案例。

接下来的内容,我们将一步一步地解决HTTP协议面临的问题,探寻其如何升级为了HTTPS协议,并在这个过程中,解释为什么有些https开头的链接,仍然被提示了不安全。

抓包实验


1. 启动wireshark,勾选所在网络

2. 双击进去之后,点击左上角红色的正方形先停止捕获

3. 填写过滤器,过滤器内容 http and ip.addr== 你的ip ,ip地址写我们需要访问的那个网站的ip,点击右边的Apply(应用),然后再点击开始重新捕获。像这样先过滤再捕获页面就干净多了,有助于后面的分析,准备抓包了。

4. 进入到网页登录的界面进行登录

5. 登录后wireshark就捕获到了数据

到这为止,我们成功抓取到了用户名及密码!

HTTP 中间人攻击


HTTP 协议使用起来确实非常的方便,但是它存在一个致命的缺点:不安全。

我们知道 HTTP 协议中的报文都是以明文的方式进行传输,不做任何加密,这样会导致什么问题呢?

下面来举个例子:

小明在 Java 贴吧发帖,内容为我爱 java:

被中间人进行攻击,内容修改为我爱 PHP:

小明被群嘲(手动狗头)

可以看到在 HTTP 传输过程中,中间人能看到并且修改 HTTP 通讯中所有的请求和响应内容,所以使用 HTTP 是非常的不安全的。

防止中间人攻击


这个时候可能就有人想到了,既然内容是明文那我使用对称加密的方式将报文加密这样中间人不就看不到明文了吗,于是如下改造:

双方约定加密方式,如下图:

使用 AES 加密报文,如下图:

这样看似中间人获取不到明文信息了,但其实在通讯过程中还是会以明文的方式暴露加密方式和秘钥,如果第一次通信被拦截到了,那么秘钥就会泄露给中间人,中间人仍然可以解密后续的通信,如下图:

那么对于这种情况,我们肯定就会考虑能不能将秘钥进行加密不让中间人看到呢?答案是有的,采用非对称加密,我们可以通过 RSA 算法来实现。

在约定加密方式的时候由服务器生成一对公私钥,服务器将公钥返回给客户端,客户端本地生成一串秘钥(AES_KEY)用于对称加密,并通过服务器发送的公钥进行加密得到(AES_KEY_SECRET),之后返回给服务端。

服务端通过私钥将客户端发送的 AES_KEY_SECRET 进行解密得到 AEK_KEY,最后客户端和服务器通过 AEK_KEY 进行报文的加密通讯。

改造如下图:

可以看到这种情况下中间人是窃取不到用于 AES 加密的秘钥,所以对于后续的通讯是肯定无法进行解密了,那么这样做就是绝对安全了吗?

所谓道高一尺魔高一丈,中间人为了对应这种加密方法又想出了一个新的破解方案,既然拿不到 AES_KEY,那我就把自己模拟成一个客户端和服务器端的结合体。

在用户→中间人的过程中中间人模拟服务器的行为,这样可以拿到用户请求的明文,在中间人→服务器的过程中中间人模拟客户端行为,这样可以拿到服务器响应的明文,以此来进行中间人攻击:

这一次通信再次被中间人截获,中间人自己也伪造了一对公私钥,并将公钥发送给用户以此来窃取客户端生成的 AES_KEY,在拿到 AES_KEY 之后就能轻松的进行解密了。

中间人这样为所欲为,就没有办法制裁下吗,当然有啊,接下来我们看看 HTTPS 是怎么解决通讯安全问题的。

如何解决HTTP明文传输的问题


HTTP协议是明文传输的,这导致它很容易被人窃取和篡改,并制约了其在更多场景的应用。

如何解决这一问题呢?一种行之有效的方法是将HTTP协议传输的内容进行加密。接下来让我们简单了解下加密的概念和用途。

加密是将明文信息改变为难以读取的密文内容,使之不可读的过程。只有拥有解密方法的对象,我们一般称之为密钥,经由解密过程,才能将密文还原为正常可读的内容。

加密是并非是一个完全现代的概念。古代的时候,一些密信的传输,会选择将内容按一定规律打乱,变成无意义的文字后再发出。不知晓这个规则的人,即便中途拦截了信件,也无法获知内容。但是收信人只要按照事前约定的规则进行反转,则可以正确知晓信件的内容。

中国宋代兵书《武经总要》是北宋仁宗时期官修的一部兵书。该书前集第15卷的“字验”一节,讲述的是加密传送军情的一套方法。先约定40种不同的军情,然后用一首含有40个不同字的诗,令其中每一个字对应一种军情。传送军情时,写一封普通的书信或文件,在其中的关键字旁加印记。军使在送信途中,不怕被敌方截获并破解信中内容。将军们收到信后,找出其中加印记的关键字,然后根据约定的40字诗来查出该字所告知的情况。

凯撒密码是公元前一世纪在高卢战争时被使用的。据传其被凯撒用于加密军事信息。它是将英文字母向前移动k位,从而生成字母替代的密表。比如k=4,则E的真实含义是A,F的真是含义是B,k就是其中的密钥。

互联网时代,加密的应用拓展到了网络生活的方方面面。计算机使用的加密算法一般会分为两类:对称加密和非对称加密。

对称加密:在对明文信息进行加密和解密时的密钥是同一个,加密的密钥即可用来解密,这种加密的算法被称为对称加密。

非对称加密:在对明文信息进行加密和解密时的密钥是两个密钥,我们假定其分别是密钥A和密钥B。密钥A加密的内容,只有密钥B能解密开,密钥A自己也无法解密。反之密钥B加密的内容,只有密钥A能解开,密钥B自己也无法解密。这种加密的算法被称为非对称加密,其中的密钥A和密钥B,习惯上被称之为公钥和私钥,公钥往往公布于网络之中,而私钥则由密钥生成者自己持有。

举个例子,对称加密就好比,你把一封信,放到了一个盒子里,这个盒子有一把锁和一把钥匙,你用钥匙将其锁上后,无论谁得到了这个盒子,没有盒子的钥匙,就无法将其打开并得知信的内容。但是只要有这个盒子的钥匙,即便是复制品,只要复制的一模一样,就可以打开。而非对称加密使用的盒子则是有两个锁孔和两把钥匙,使用钥匙A把盒子上锁之后,钥匙A自己打不开,必须使用钥匙B才能打开这个盒子,反之亦然。

非对称加密由于将加密和解密的密钥分开了,故而其破解难度会比对称加密难很多,所以安全性更强。但是这种安全性牺牲了加密的速度。也就是说,加密同样大小的内容,对称加密会比非对称加密快很多。所以在传输大量内容时,优先选择的加密算法往往还是对称加密算法。在后续的内容中,我们可以看到,HTTPS协议是如何同时利用对称加密和非对称加密各自的特点。

加密就足够了吗?


了解到加密的概念后,你可能会觉得,那我们在网络上传输内容前,将内容加密下再传输,那这样中间人不就无法窃取或篡改内容了吗?

单纯就传输的内容而言,确实如此。但是另一个问题也随之而来,密文传输过去了,密钥要怎么传输过去呢?没有密钥,即便将密文传输过去,对方也无法解密,只能拿到一堆毫无意义的符号。

如果将密钥明文传输过去,那中间人连你使用的密钥一起拦截了,那他可以使用这个密钥解密传输的内容,伪造后再重新加密,本质上和拦截了明文是一样的。

那我们将密钥也加密传输呢?那密钥的密钥如何传输,又会成为一个问题。无论我们如何给密钥套娃,套到最后的密钥,它的传输安全性总是无法保证的。

如果说只有一个密钥的对称加密无法妥善的解决密钥传输的问题,那拥有两个不同密钥的非对称加密能够解决这个问题吗?我们可以设想一下,通信双方的其中一端,比如说服务端,提前生成好了一对非对称加密的密钥,将私钥留给自己用,而将公钥公布于网络之中,以便于客户端取用。

客户端在向服务端发送数据的时候,先使用服务端的公钥进行加密,而后再进行传输。这时中间人虽然也知道服务端的公钥(因为服务端的公钥必须向每一个可以请求其网站的客户端提供),但是由于非对称加密算法的加密和解密不是同一个密钥的特性,中间人无法通过这个密钥解密客户端的传输的信息,进而也就无法窃取和篡改了。

然而仅仅这样还是不够的。一来,中间人虽然无法通过服务端的公钥窃取客户端发出的信息,但是他仍然可以使用这个公钥解密服务端发送给客户端的信息。因为服务端发送给客户端的信息是使用服务端的私钥加密的,自然可以被服务端的公钥解开。二来,也更重要的是,中间人可以将客户端获取服务端公钥的链路拦截,然后将服务端的公钥替换为自己生成的非对称加密密钥的公钥。这样一来,客户端拿到的是一个被伪造的服务端公钥,即使使用这个公钥加密后再传输,中间人可以直接使用其生成的私钥解密,窃取或篡改信息后,再使用原先的服务端公钥加密之后发送给服务端。如此一来,加密也形同虚设,中间人可以再次完全窃取甚至篡改客户端和服务端之间通信的内容。

所以无论是对称加密还是非对称加密,都要面临密钥传输的问题。回看我们先前列举的将信件打乱的例子,你会发现所谓的密钥(信的规则)都是事先告知对方的,而非随着传输内容一起传输过去。因为既然传输内容的渠道有泄露的风险,那怎么能再信任它去传输更为机密的密钥呢?

然而网络的场景要比传递信件和电报的场景更为复杂。因为在我们访问网站之前,网站和我们都无法事先得知对方的存在,更遑论提前交换密钥了。所以我们只能在访问网站的时候完成交换密钥这一过程。如何在一条有可能被泄露内容的渠道上,安全地完成密钥的交换呢?

用来交换密钥的证书认证机构


如果单纯依靠浏览器和网站两方,已经无法安全地完成密钥交换这一过程了,那是否可以引入第三方来帮忙一起完成这个事情呢?CA机构就是被设立用来做这个事情的。

CA机构,全称证书认证机构(英语:Certificate Authority,缩写为CA),是为负责发放和管理数字证书第三方权威机构。这里有比较两个陌生的名词,『证书』和『认证』。这两个名词的含义是什么样的,CA机构是如何完成传输密钥这一工作的呢?

当一个网站上线前,网站的维护者需要找一个可信的,权威的CA机构,申请一份自己网站的证书。网站维护者大致需要提供这些资料:1. 网站的域名;2. 自身组织(公司)信息及拥有该域名的证明;3. 该网站的非对称加密密钥的公钥(私钥则由网站自行存储)。这一过程,不能通过明文的网络传输进行,必须通过其他可信的加密通道传输这些信息,以避免服务端的公钥被攻击者给替换掉。

CA机构会审核网站维护人的身份,确认可信后,会向其颁发一个网站证书。这个证书的本质什么呢?就是将上述网站维护者所提交的信息,使用CA机构的非对称加密的私钥,进行加密后的密文。也就是说证书证明了,某个网站所拥有的公钥及其归属的组织。一般而言,证书同时会标记有效期,一旦证书过期,则会被认为不可信。

我想到这里你已经大致了解『证书』和『认证』的概念了。所谓证书,就是CA机构使用自己的私钥对网站的信息和公钥进行加密后的一串密文。所谓认证,就是CA机构审核这个网站的信息真实可靠,并对其使用自己的私钥加密的过程。

注意这里我们已经用到了两对非对称加密的密钥了。一对是网站的服务器所持有的,其私钥由网站自行存储,公钥则会送往CA机构进行加密生成网站证书。另一对是CA机构所持有的,其私钥被用于加密网站所提交的信息,尤其是网站的公钥,CA机构的公钥我们目前还没有提及。

对于使用了证书的链接,我们可以打开浏览器地址栏旁边的小锁标识,其中会有浏览器获取到的该网站服务器证书的信息。下图是获取到的baidu.com这个网址的证书信息。我们可以看到,这个证书是被颁发给百度公司的,认证的域名是baidu.com,而为这个证书认证的CA机构是GlobalSign。同时证书中还包括了有效期,证书里含有的服务端公钥等信息。

使用证书之后如何交换密钥?


当网站获取到CA机构颁发的证书之后,就可以将网站提供的HTTP协议升级为HTTPS协议了。那使用证书的HTTPS协议,是如何建立链接并交换密钥及传输信息的呢?

当客户端(比如浏览器)和服务端(网站)建立链接后,客户端会首先向服务端请求该网站认证的证书。

获得证书后,客户端会使用CA机构的公钥将证书解密。这样,客户端就获得了网站所持有的非对称加密密钥的公钥。得到网站的公钥之后,客户端并不会使用这个公钥直接加密传输的内容,而是使用其加密自己生成的一个对称加密的密钥。我们姑且称之为数据密钥,这个对称加密的密钥将被用来加密那些真正要传输的信息。

随后被加密的数据密钥被发送到网站服务端,服务端使用自己存储的私钥将被加密的数据密钥解密,这样服务端也获得了数据密钥。

至此,客户端和服务端都获得了传输内容的加密密钥,他们之间的通信则可以使用这个密钥加密后进行传输而无需担心被泄露和篡改的风险。

还记得前文中我们提到的,对称加密和非对称加密的优缺点吗?对称加密的优点是加解密速度快,但是非对称加密的优点是加密和解密的密钥不同,可以实现安全等级更高的传输。所以在这个流程中,服务端和客户端选择使用非对称加密的方法来传输一个对称加密的数据密钥,因为密钥往往相对比较短,所以使用非对称加密也不会太慢。但是而后大量的内容传输则使用这个数据密钥进行对称加密,以此同时利用两种加密方法的优点。

需要注意的是,这里的数据密钥一定是客户端重新生成的一份新的对称加密密钥,不能由服务端生成或者直接使用证书里的服务端的公钥来进行加密,否则便会有安全漏洞。

如果由服务端来生成这个密钥,那只能是使用服务端的私钥来对其进行加密,客户端使用证书里的服务端公钥对其进行解密,最终获得该数据密钥。这样做的问题在于,服务端的证书是公开的,换言之,中间人同样可以通过这个证书解密并获取到这个数据密钥。

如果是直接使用证书里的服务端公钥,即使不考虑非对称加密的效率问题,直接使用这个公钥也是不安全的。如果客户端和服务端约定的是使用这个公钥进行数据的加解密,其实中间人也是可以知道这个公钥的。虽然证书的存在使得中间人无法轻易地给客户端替换掉服务端的公钥,非对称加密的特性也使其无法解密客户端向服务端发送的加密数据,但是中间人可以使用这个公钥轻松解密服务端给客户端发送的数据,而且可以使用这个公钥,假装客户端向服务端发送信息。

所以客户端和服务端传输数据使用的密钥,一定是客户端生成后,再使用证书中服务端的公钥加密后再传输的,因为服务端公钥加密后的内容是唯一中间人无法破解和获取的数据。

证书一定是真的吗?


虽然上述的所描述的几个流程,确实是HTTPS协议在建立链接及传输信息时真正使用的流程,也并无遗漏。但是仅仅只有这些流程是不足以保证信息的安全传输的。这些流程严格来说,和我们最开始提出的把密再加一次密的套娃方案也没有太大差别,只不过是非对称加密和对称加密混着套而已。

这个方案目前还存在着这样一个漏洞。既然中间人有可能窃听和伪造信息,甚至拦截和伪造密钥。那如果他直接把客户端建立链接时,请求的网站服务端的证书给伪造了。那后续的内容,即使仍按照原流程进行加密,中间人仍然可以破解。

我们可以在深入地解析一下如果证书被中间人伪造了,会发生什么。以及中间人如果想要破解证书,需要什么条件。

假如客户端拿到的证书是被中间人伪造的证书。也就是说,证书里的内容,尤其是网站服务端的公钥,可能已经被中间人替换为他自己生成的一对非对称加密的公钥了。这个时候,又回到了直接使用非对称加密来进行传输时的问题。客户端拿着虚假的网站公钥,加密自己生成的数据密钥后,并发送给服务端。中间人就可以拦截这个被加密的数据密钥,并使用自己的私钥将其解密,如此就可以获知客户端和服务端传输信息的数据密钥。随后中间人再假装客户端将这个数据密钥继续发给服务端,使两者后续继续使用这个已被泄露的密钥进行加密通信。那中间人手握这个被泄露的密钥,可以和查看明文一样,查看两者通信的内容了。

那中间人如果想要伪造证书,需要什么条件呢?经过前文的描述,我们已经知道,网站的证书本质上是CA机构使用自身的非对称加密的私钥加密的一段密文。如果中间人可以获知CA机构的私钥,那就可以伪造这个CA机构认证过的所有证书了。但是我们也提到过,CA机构往往都是第三方、可信的、权威的机构,根本没有动机去协助中间人进行攻击(当然,世事无绝对,下文我们会简单讲解下CA机构是如何取信于大众的)。而且在整个加密过程中,CA机构的私钥是完全被CA机构自身持有,并没有暴露到网络上来的。也就是说,中间人想要仅仅利用网络的传输就获取到CA机构的密钥是几乎不可能的。

这时,中间人还有第二个方案可以选择,就是自己生成一对非对称加密的密钥,然后使用其中的私钥,代替CA机构的私钥,签名伪造服务端的证书。这个时候,只要中间人能够把客户端拿到的CA机构的公钥,替换成自己生成的这一对非对称加密密钥的公钥,那就可以在客户端毫无感知的情况下实现偷龙转凤,再次完成伪造证书的工作。

讲到这里,不知道大家发现没有,整个过程中,对于CA机构的公钥,我们只讲到了客户端使用CA机构的公钥解密网站的证书,而没有讲到客户端是如何拿到CA机构的公钥的。而现在,我们又发现,客户端获取CA机构公钥的这一步过程竟然也是有可能被攻击的,而且一旦被攻击成功之后,我们先前套的娃都白套了,中间人一样可以知悉我们和网站之间传输的内容。

那HTTPS协议中又如何保证客户端获取CA机构的公钥这一步的安全性的呢?解决方案可能会让你大跌眼镜。现实中的解决方案是,CA机构提前将自己的公钥告知操作系统的厂商,操作系统厂商将其放入操作系统中,在操作系统安装时,CA机构的密钥就已经保存到到我们的电脑和手机上了。也就是说,CA机构的公钥根本不会通过网络传输,而是几乎以一种物理交付的方式,交到客户端手上的。而中间人除非能够获取到客户端操作系统的密码,否则仅仅通过网络,也无法修改或替换客户端上的CA机构的公钥。

HTTPS 简介


HTTPS 其实是 SSL+HTTP 的简称,当然现在 SSL 基本已经被 TLS 取代了,不过接下来我们还是统一以 SSL 作为简称。

SSL协议其实不止是应用在 HTTP 协议上,还在应用在各种应用层协议上,例如:FTP、WebSocket。

其实 SSL 协议大致就和上一节非对称加密的性质一样,握手的过程中主要也是为了交换秘钥,然后再通讯过程中使用对称加密进行通讯。

大概流程如下:

这里我只是画了个示意图,其实真正的 SSL 握手会比这个复杂的多,但是性质还是差不多,而且我们这里需要关注的重点在于 HTTPS 是如何防止中间人攻击的。

通过上图可以观察到,服务器是通过 SSL 证书来传递公钥,客户端会对 SSL 证书进行验证,其中证书认证体系就是确保 SSL 安全的关键,接下来我们就来讲解下 CA 认证体系,看看它是如何防止中间人攻击的。

CA 认证体系


大上一节我们看到客户端需要对服务器返回的 SSL 证书进行校验,那么客户端是如何校验服务器 SSL 证书的安全性呢。

权威认证机构在 CA 认证体系中,所有的证书都是由权威机构来颁发,而权威机构的 CA 证书都是已经在操作系统中内置的,我们把这些证书称之为CA根证书:

签发证书我们的应用服务器如果想要使用 SSL 的话,需要通过权威认证机构来签发 CA 证书,我们将服务器生成的公钥和站点相关信息发送给 CA 签发机构,再由 CA 签发机构通过服务器发送的相关信息用 CA 签发机构进行加签。

由此得到我们应用服务器的证书,证书会对应的生成证书内容的签名,并将该签名使用 CA 签发机构的私钥进行加密得到证书指纹,并且与上级证书生成关系链。

这里我们把百度的证书下载下来看看:

可以看到百度是受信于 GlobalSign G2,同样的 GlobalSign G2 是受信于 GlobalSign R1。

当客户端(浏览器)做证书校验时,会一级一级的向上做检查,直到最后的根证书,如果没有问题说明服务器证书是可以被信任的。

如何验证服务器证书那么客户端(浏览器)又是如何对服务器证书做校验的呢?

首先会通过层级关系找到上级证书,通过上级证书里的公钥来对服务器的证书指纹进行解密得到签名(sign1),再通过签名算法算出服务器证书的签名(sign2)。

通过对比 sign1 和 sign2,如果相等就说明证书是没有被篡改也不是伪造的。

这里有趣的是,证书校验用的 RSA 是通过私钥加密证书签名,公钥解密来巧妙的验证证书有效性。

这样通过证书的认证体系,我们就可以避免了中间人窃取 AES_KEY 从而发起拦截和修改 HTTP 通讯的报文。

根CA和中间CA


上文的介绍中,为了突出重点,我们并没有介绍根CA和中间CA的概念。在实际场景中,CA机构通常会被划分为根CA和中间CA机构两种。

上文我们所说的向网站服务端提供认证服务的CA机构,一般是指中间CA机构。而根CA机构,则是为中间CA机构签发证书的CA机构。所以根CA机构往往又被成为CA的CA。

如何理解这个CA的CA呢?回想下上一节,中间CA机构需要提供的能力有哪些?一方面,他需要提供自己的私钥给网站服务端的公钥签发证书。另一方面,他需要将自己的公钥安全地交到用户手上。而根CA机构作为CA的CA,同样需要提供这两种能力。一方面,根CA机构需要提供自己的私钥给中间CA机构的公钥签发证书。另一方面,根CA机构需要将自己的公钥安全地交到用户手中。相对应地,由于根CA机构的存在,中间CA机构无需再考虑将自己的公钥交给用户这一流程,而是将其交于根CA机构签发证书即可。用户的操作系统中,也只需要安装根CA机构的公钥,而无需安装中间CA机构的公钥,习惯上,我们将安装在操作系统中的根CA机构的公钥信息称之为根证书。

下图是安装在macOS系统中的根证书列表(访问路径为:钥匙串访问->证书)。我们可以看到图中打开了的这张根证书的一些详细信息。这个根证书的CA机构是digicert,该机构是全球最大的证书认证机构。我们还可以看到这个证书的过期时间,公钥等信息。

引入了根CA机构之后,客户端获取服务端的密钥也会多几个步骤。当客户端从网站服务端获取到服务端的证书之后,可以从证书之后获取签发该证书的中间CA机构信息。这时,客户端的操作系统中可能并没有中间CA机构的公钥信息。所以客户端需要再次去请求获取中间CA机构的证书,从中间CA机构的证书中,可以获取到为该中间CA机构签发证书的根CA机构的信息。随后再利用操作系统中自带的根证书,将中间CA机构的证书解密,即可获得中间CA机构签发证书的公钥,随后再使用这个公钥解密网站服务端的证书,即可获得网站服务端的公钥了。

区别根CA和中间CA的原因,主要还是在于CA机构的私钥实在是太过重要了。所以选择在根CA机构之前加一层中间CA机构,由中间CA机构提供其私钥对网站服务端签发证书,而尽可能少地暴露根CA机构的私钥,以此来减少根CA机构私钥泄露的可能性。

我们凭什么信任CA机构


讲到这里,大家或多或少都会有一些感觉,客户端和服务端之间传输安全的命脉,一步步地被转交到了CA机构那里,甚至还要无条件地信任CA机构。CA机构所持有的私钥,是签发服务端证书的『合法凭证』。而这个私钥一旦被泄露,或者CA机构内部利用这个密钥做一些窃密的事情,对于整个互联网的证书信任体系和安全体系都是一次非常致命的打击。

那CA机构做了哪些措施,才使得大众相信他们可以做好这个传输密钥的第三方的角色呢?以下内容是从全球最大的数字证书认证机构digicert的官网摘录的部分措施。大家可以通过这一小部分的措施窥见CA机构的安全措施有多严格。

访问控制和身份验证: 所有用户与 DigiCert 系统的交互都可以追溯到执行该操作的具体人员,并且所有用户在能够与 DigiCert 系统交互之前必须得到明确的身份识别。DigiCert 人员必须首先向 DigiCert 系统验证自己的身份,然后才能访问执行其受信任角色所需的任何系统组件,并且角色由 DigiCert 的认证实践声明和信息安全政策定义。

人员控制:所有有权访问 DigiCert 数据和/或系统的 DigiCert 员工和其他工作人员均须遵守保密协议,并需要通过背景调查并接受基于角色的特定培训。

物理安全控制:对包含敏感信息的每个办公室、计算机房和工作区域的访问均受到物理限制。所有办公室门均配有门禁,并且 DigiCert 设施的所有入口始终处于锁定状态。这些入口可通过门禁卡或其他门禁设备进入,该门禁卡或其他门禁控制设备是在确认背景调查干净后颁发的。DigiCert 数据中心和办公室均受到监视器监控。密钥存放室需要生物识别和双重保管人员认证才能进入。所有访问都会被记录。

当然只是由CA机构自己出台安全制度还是不够的。一般政府会出台国家标准来规定CA机构设立应当满足的标准,比如中国政府出台的GB/T 25056-2018等标准。

除此之外,公众的信任对于一家CA机构而言是最重要的资产,这个资产是那么的不可撼动但却又那么的脆弱。对于一家已经取信于公众的大型CA机构而言,几乎没有其他竞争对手可以成规模地抢夺他的用户或是夺走公众对他的信任。但是同样地,一旦这家信任机构自身出现了任何一个严重的安全漏洞,即便其及时地补救,公众也再难重建对其的信任,而是会逐渐转投其他CA机构。所以说一家CA机构如果想要长久地经营下去,必须采取足够的措施,保护其敏感信息诸如机构私钥的安全性。这既是保护公众对他的信任,也是保护机构本身。

回到最初的问题


回到本文最初的问题,浏览器为什么会提示你:『与此网站之间建立的链接不安全』呢?有这样几个原因。

首先,也是我们前文讲到的,你正在使用HTTP协议访问网站的内容。浏览器认为你使用明文的HTTP协议访问内容时,内容有较大的被泄露和篡改的风险,因此做出提示。

那使用HTTPS协议访问网站就一定是安全的吗?也不尽然,通过本文的学习相信你也能了解到,HTTPS协议中,客户端是通过验证证书的方式,来确认获取到服务端的公钥是没有被篡改的。因此,如果HTTPS的证书出现了问题,那浏览器仍然可能提示你访问网站的链接不安全。

一类情况是证书本身变得不合法了。比如浏览器证书的有效期过期了,或是证书并没有得到CA机构的认证,如果一个证书没有得到CA机构的认证,那就无法保证这个证书确实是这个网站的,因为获取证书的过程有可能被伪造。

另一类情况是证书内携带的信息不匹配,比如下面这个例子,请求的是tieba.com这个网站的证书,但是返回的是baidu.com这个域名的证书。

当然我们知道,百度贴吧本身是归属百度的产品。当你请求一个网站,结果拿到的证书中认证的域名和你请求的域名毫不相关。那你可能要留意一下这里面的安全风险了。

总结


本文介绍了HTTP协议和HTTPS协议,从浏览器对网站链接安全的提示开始,向大家解释了HTTPS协议在网络传输中,如何保证传输内容不被泄露和篡改,以及如何尽可能安全的与网站建立链接。

HTTPS协议解决了HTTP协议明文传输的缺陷,避免了中间人攻击。但是需要注意的是,HTTPS协议解决的是网络中一个端到另一个端传输内容不可泄露及被篡改的需求,针对的是内容在网络中传输的这一阶段。HTTPS协议无法保护操作系统本身的漏洞。如果攻击者直接攻破了其中一个端的操作系统,比如获取了你的操作系统的密码,那他甚至可以直接替换掉操作系统中的根证书,HTTPS协议的保护也就无从谈起了。

另外,大多数情况下,HTTPS协议无法避免服务端获取你在网站中存储的内容,比如你在微信中的聊天记录。因为绝大多数的网站和APP,通信的两端是客户端和网站服务端。也就是说HTTPS协议保护从你的设备到网站服务器之间的网络传输内容不被窃取。但是这段内容到达服务端之后,就会被解密。服务端拿到的内容就是传输的明文。所以使用HTTPS协议并不代表腾讯公司拿不到你的微信聊天记录。如果真的想实现不被网站服务端获取到聊天记录的消息APP,那只能在不通过消息APP服务端的前提下,和聊天的对方交换密钥,然后将聊天内容加密后再发送。这种场景下,如果采用HTTPS协议,那通信的两端应当是聊天的两台客户端设备,而非客户端和网站服务端。

出于篇幅和复杂度的考虑,本文省略了HTTPS协议中关于哈希校验相关的部分,读者如有兴趣可自行查询资料了解。

作者虽然是计算机的科班生,但是在第一次了解到HTTPS整个证书认证体系及这个体系需要解决的安全问题后,第一反应是非常惊讶于前人这些精妙的设计,环环相扣,不留疏漏。而在了解到根证书竟然是随着操作系统直接安装在计算机上,而非是通过网络传输的时候,则更多感慨,网络再精彩,也不过是虚拟的世界,像根证书这种涉及整个网络安全根基的东西,竟然是使用物理交付的方式。

网络终究离不开现实。正如对于PB以上级别的数据传输,最快的方式可能是使用卡车运输磁盘。想要打游戏有更短的时延,最快的方式可能是在游戏服务器地理位置的旁边接入。而事关整个网络传输安全的密钥,则是在你购买计算机时,亲手交到了你的手上。