为了能更好的讲给面试官听,我写了一个简化版,看不懂的看下面的明细

要解决的问题:客户端和服务端交互,如何不让交互的数据泄露

方案一:对称加密,秘钥无法传输

方案二:非对称,无法验证服务器给的秘钥的真实性,那么如果服务器对秘钥进行签名呢?

方案三:非对称+签名,验签的时候依然不行,因为没有验签的秘钥。

问题在于,无论采用哪种加密方式,我们都没法保障秘钥在传输过程的中的安全性,所以考虑能不能不传输,在操作系统或浏览器中内置秘钥呢?但内置谁的秘钥呢?我每天要访问那么多网站,不可能操作系统内置所有网站的秘钥吧?所以考虑内置一个第三方的秘钥,这个第三方我们叫证书机构,其他网站会先用自己的公钥去找证书机构,采用证书机构的私钥进行加密,生成证书。客户端用系统内置的证书机构的公钥进行解密,能解开,说明证书没有确实是第三方生成的。但问题在于第三方机构会给很多公司都生产证书,如果黑客也去申请一张证书,实际上你本机的公钥是可以解开的,那么就考虑在证书中再写上服务器的域名,同时为了避免黑客修改证书换成自己的域名再对证书进行签名,同时对这个签名再使用第三方的私钥加密一次。所以一张证书实际上包含了三个主要的东西


  1. 域名
  2. 服务器公钥
  3. 证书签名后的加密串

除此之外证书还包含一些其他的东西,比如证书的有效期,证书的签发机构等

缘起

随着互联网的高速发展,安全问题也日益严重,传统的http已经不能满足安全方面的需求。各大搜索引擎也默认给http的网站降权,各大浏览器也会在用户访问网站的时候提示此网站使用的是http,是一个不安全的网站。如此下来,https则呼之欲出。这里一chrome为例,可以看到http的网站会提示不安全

Https原理详解(http和https对比)_https收费

而如果是https的网站则会提示安全

Https原理详解(http和https对比)_客户端_02

那么https相对http究竟是怎么做到安全的呢?他的原理是怎样的呢?下面来一起探究。

在说https的原理之前我们先说说http的原理以及为什么说http不安全

http原理

http的访问过程

Https原理详解(http和https对比)_http和https对比_03

可以看到与其说http的原理不如说http就没什么原理,就是很简单的客户端访问服务端服务端给应答的过程,那么这样的一个过程有什么安全问题呢?

http的安全问题

如果我是黑客,我是不是可以再客户端和服务端通讯的中间做一个拦截呢?

Https原理详解(http和https对比)_服务器_04

下面我们来试一下,通过抓包工具Wireshark,我们来抓一下www.bxoon.com这个网站的包,这是一个http的网站

Https原理详解(http和https对比)_http和https对比_05

可以看到能够抓取到用户名和密码

所以 HTTP 传输面临的风险有:

(1) 窃听风险:黑客可以获知通信内容。

(2) 篡改风险:黑客可以修改通信内容。

(3) 冒充风险:黑客可以冒充他人身份参与通信。

HTTP 向 HTTPS 演化的过程

关于加密算法这一块以下不做过多的阐述,但为了便于理解会简单提一嘴,读者若有不明之处,建议读者先行其他方式了解加密算法再来看本文章。

使用对称加密

第一步:为了防止上述现象的发生,人们想到一个办法:对传输的信息加密(即使黑客截获,也无法破解),这里使用的是对称加密,客户端和服务端约定一个秘钥,客户端发送的时候用这个秘钥加密,服务端再解密。

Https原理详解(http和https对比)_https收费_06

但此种方式的缺点是:

(1)不同的客户端、服务器数量庞大,所以双方都需要维护大量的密钥,维护成本很高。(解释:比如我必须要保存www.baidu.com的秘钥,我又要保存www.12306.cn的秘钥,我还要保存www.taobao.com的秘钥,等等等等,而对于百度,12306,淘宝来说他们又要保存每一位用户的秘钥,那这样岂不是要累死??

(2)因每个客户端、服务器的安全级别不同,密钥极易泄露

(3)如何约定这个秘钥呢?总不能我每次访问百度的时候打个电话给百度说我们接下来用什么什么秘钥吧?通过网络约定吗?那如果这个约定的过程被黑客窃听了那黑客就知道你们约定的秘钥是什么了。

使用非对称加密

第二步:既然使用对称加密时,密钥维护这么繁琐,那我们就用非对称加密试试。非对称加密只需要维护一套公私钥就可以了。

Https原理详解(http和https对比)_客户端_07

如上图所示,客户端用公钥对请求内容加密,服务器使用私钥对内容解密,反之亦然,但上述过程也存在缺点:

(1)公钥是公开的(也就是黑客也会有公钥),所以第 ④ 步私钥加密的信息,如果被黑客截获,其可以使用公钥进行解密,获取其中的内容

对称加密和非对称加密联合使用

第三步:非对称加密既然也有缺陷,那我们就将对称加密,非对称加密两者结合起来,取其精华、去其糟粕,发挥两者的各自的优势

Https原理详解(http和https对比)_服务器_08

如上图所示

(1)第 ③ 步时,客户端说:(咱们后续回话采用对称加密吧,这是对称加密的算法和对称密钥)这段话用公钥进行加密,然后传给服务器(解释:相当于客户端与服务端每次通讯前先约定一个秘钥,而这个秘钥是用服务器给的公钥加密过的。)

(2)服务器收到信息后,用私钥解密,提取出对称加密算法和对称密钥后,服务器说:(好的)对称密钥加密

(3)后续两者之间信息的传输就可以使用对称加密的方式了

这种方式还是有问题

(1)第一步是使用服务器给的公钥对后续约定的私钥进行加密,但是这里怎么获取服务器给的公钥呢?你如何确定你访问的服务器不是黑客返回给你的呢?如下图

Https原理详解(http和https对比)_https原理详解_09

黑客在第一步就给你一个假的公钥,让你以为是服务器给你的公钥,那后续的通讯都凉凉。

数字证书

那有木有一种方式既可以安全的获取公钥,又能防止黑客冒充呢? 那就需要用到终极武器了:SSL 证书。

既然服务器需要将公钥传给客户端,这个过程本身是不安全,那么我们为什么不对这个过程本身再加密一次?可是,你是使用对称加密,还是非对称加密?这下好了,我感觉又进了鸡生蛋蛋生鸡问题了。

问题的难点是如果我们选择直接将公钥传递给客户端的方案,我们始终无法解决公钥传递被中间人调包的问题。

所以,我们不能直接将服务器的公钥传递给客户端,而是第三方机构(CA)使用它的私钥对我们的公钥进行加密后,再传给客户端。客户端再使用第三方机构的公钥进行解密,这次第三方机构的公钥不传来传去了,我们直接让微软或者谷歌在他们的操作系统或者浏览器中内置好公钥(事实上https也正是这么做的),这样公钥不就没法被替换了吗?。

下图就是我们设计的第一版“数字证书”,证书中只有服务器交给第三方机构的公钥,而且这个公钥被第三方机构的私钥加密了:

第一版数字证书的内容

Https原理详解(http和https对比)_客户端_10

如果能解密,就说明这个公钥没有被中间人调包。因为如果中间人使用自己的私钥加密后的东西传给客户端,客户端是无法使用第三方的公钥进行解密的。

话到此,我以为解决问题了。但实际上还有问题,第三方机构不可能只给你一家公司制作证书,它也可能会给中间人这样有坏心思的公司发放证书。这样的,中间人就有机会对你的证书进行调包,客户端在这种情况下是无法分辨出是接收的是你的证书,还是中间人的。因为不论中间人,还是你的证书,都能使用第三方机构的公钥进行解密。像下面这样:

Https原理详解(http和https对比)_客户端_11

客户端能解密同一家第三机构颁发的所有证书:

Https原理详解(http和https对比)_https收费_12

最终导致其它持有同一家第三方机构证书的中间人可以进行调包:

Https原理详解(http和https对比)_https原理详解_13

有人说,这简单啊,我们在证书里面再加一点信息,比如加上我们自己网站的域名,如下面这样

Https原理详解(http和https对比)_服务器_14

而你的证书是

Https原理详解(http和https对比)_服务器_15

这样你没法用你的去替换我的吧?毕竟用户拿到你的证书后验证一下域名是否与当前访问的一致就知道拿到的证书对不对了。但是,我们要知道,证书也是可以修改的,我完全可以把我证书中的www.taobao.com修改成www.baidu.com.然后再发给你,这样你又以为证书是真的证书了,那怎么办呢?我们可以不可以对证书先进行一次数字签名再把这个签名也发送给客户端呢?类似下面这样

Https原理详解(http和https对比)_客户端_16

这样你一修改证书中的域名,你的数字签名就不对了,客户端拿到这个证书后也对证书内容进行一次MD5然后拿得到的签名与你传过来的做下对比,对比相等则说明证书内容没有被改过。但是这里还是有问题,比如我是www.taobao.com.我把我的证书域名改成www.baidu.com。然后我也md5一下,同时我再把证书中的数字签名也替换成我新的MD5值,那这样,客户端又会以为我的证书是真的证书了,那怎么办呢?这里又要用到第三方机构。

下面看终极版本

Https原理详解(http和https对比)_https收费_17

我们使用第三方机构的私钥对证书的数字签名进行加密,客户端再使用第三方机构的公钥(系统和浏览器内置)进行解密得到明文签名,然后对证书内容进行md5,最后比较这两个值是否相等。如果修改了证书内容比如域名,那得到的数字签名就会不一样,而修改者由于没有第三方的私钥,没法对修改后的数字签名进行加密。这样就可以做到防篡改。而同一家机构申请的证书由于证书内容(含网站域名)不一样,浏览器也可以轻易分辨证书是否被替换。而这,也正是https的证书原理。

后续步骤

经过一顿骚操作之后,客户端终于拿到服务器给的公钥,可以确定这个公钥不是中间商替换过的公钥了,然后会有以下步骤


  1. 客户端生成一个私钥
  2. 客户端用前面的公钥来加密这个私钥
  3. 客户端把加密后的串传输给服务端
  4. 后续通信采用这个私钥来通信

如果中间商在第三步给了一个假的

数字证书的制作过程

Https原理详解(http和https对比)_https收费_18

现实中,浏览器和操作系统都会维护一个权威的第三方机构列表(包括它们的公钥)。因为客户端接收到的证书中会写有颁发机构,客户端就根据这个颁发机构的值在本地找相应的公钥。

证书内容有哪些

SSL 证书中包含的具体内容有:

(1)证书的发布机构CA

(2)证书的有效期

(3)公钥

(4)证书所有者

(5)签名

浏览器验证证书的步骤

客户端在接受到服务端发来的SSL证书时,会对证书的真伪进行校验,以浏览器为例说明如下:

(1)首先浏览器读取证书中的证书所有者、有效期等信息进行一一校验

(2)浏览器开始查找操作系统中已内置的受信任的证书发布机构CA,与服务器发来的证书中的颁发者CA比对,用于校验证书是否为合法机构颁发

(3)如果找不到,浏览器就会报错,说明服务器发来的证书是不可信任的。

(4)如果找到,那么浏览器就会从操作系统中取出 颁发者CA 的公钥,然后对服务器发来的证书里面的签名进行解密

(5)浏览器使用相同的hash算法计算出服务器发来的证书的hash值,将这个计算的hash值与证书中签名做对比

(6)对比结果一致,则证明服务器发来的证书合法,没有被冒充

(7)此时浏览器就可以读取证书中的公钥,用于后续加密了

数字证书的分类

Https原理详解(http和https对比)_https收费_19

Https原理详解(http和https对比)_客户端_20

数字证书如何获取和收费

说到数字证书如何获取就要先说说数字证书的颁发机构(CA),全球有数百家权威的数字证书颁发机构,当然比较权威的全球好像不超过5家,比较常见的有赛门铁克(Symantec),沃通等等。

Https原理详解(http和https对比)_服务器_21

当然要付钱,而且,还不便宜。证书还分为很多种的,比如域名型DV SSL证书、企业型OV SSL证书、增强型EV SSL证书、通配符SSL证书、多域SSL证书、代码签名证书、PDF文档签名证书等等,每一种价格都不太一样,这里截取了一份沃通的价格表供参考。

Https原理详解(http和https对比)_http和https对比_22

当然也可以自己生成数字证书,如何生成是属于证书的生成和部署方面的问题,本处不做阐述,读者可以自行查阅资料。

本文在写的时候参考了大量资料,由于笔者很多资料看了就关了,在此就不一一列出,如有侵权还请告知。

参考:https://showme.codes/2017-02-20/understand-https/