目录

一、HTTP 为什么不安全

1.窃听风险

2.篡改风险

3.冒充风险

二、安全通信的四大原则(机密性、完整性,身份认证和不可否认)

三、HTTPS 通信原理简述

1.对称加密:HTTPS 的最终加密形式

2.非对称加密:解决单向对称密钥传输问题

3.数字证书,解决公钥传输信任问题

问题一:如何验证证书的真实性,如何防止证书被篡改

问题二:如何防止证书被调包

4.HTTPS中的数字证书和数字签名

4.1 https 中数字证书和数字签名定义

4.2 数字证书的生成过程以及验证机制

四、其他 HTTPS 相关问题

1.什么是双向认证

2.什么是证书信任链

总结


用20张图由浅入深地把 HTTPS 讲明白。

一、HTTP 为什么不安全

HTTP是明文传输,主要存在三大风险。

1.窃听风险

中间人可以获取到通信内容,由于内容是明文,所以获取明文后有安全风险。

2.篡改风险

中间人可以篡改报文内容后再发送给对方,风险极大。

3.冒充风险

比如你以为是在和某宝通信,但实际上是在和一个钓鱼网站通信。

HTTPS 显然是为了解决这三大风险而存在的,接下来我们看看 HTTPS 到底解决了什么问题。

二、安全通信的四大原则(机密性、完整性,身份认证和不可否认)

看了上一节,不难猜到 HTTPS 就是为了解决上述三个风险而生的,一般我们认为安全的通信需要包括以下四个原则: 机密性、完整性,身份认证和不可否认。

如下:

  • 机密性:即对数据加密,解决了窃听风险,因为即使被中间人窃听,由于数据是加密的,他也拿不到明文。

  • 完整性:指数据在传输过程中没有被篡改,不多不少,保持原样,中途如果哪怕改了一个标点符号,接收方也能识别出来,从而判定接收报文不合法。

  • 身份认证:确认对方的真实身份,即证明「你妈是你妈」的问题,这样就解决了冒充风险,用户不用担心访问的是某宝结果却在和钓鱼网站通信的问题。

  • 不可否认: 即不可否认已发生的行为,比如小明向小红借了 1000 元,但没打借条,或者打了借条但没有签名,就会造成小红的资金损失。

接下来我们一步步来看看 HTTPS 是如何实现以满足以上四大安全通信原则的。

三、HTTPS 通信原理简述

1.对称加密:HTTPS 的最终加密形式

既然 HTTP 是明文传输的,那我们给报文加密不就行了,既然要加密,我们肯定需要通信双方协商好密钥吧,一种是通信双方使用同一把密钥,即对称加密的方式来给报文进行加解密。

如图示:使用对称加密的通信双方使用同一把密钥进行加解密。

对称加密具有加解密速度快,性能高的特点,也是 HTTPS 最终采用的加密形式,但是这里有一个关键问题,对称加密的通信双方要使用同一把密钥,这个密钥是如何协商出来的?

如果通过报文的方式直接传输密钥,之后的通信其实还是在裸奔,因为这个密钥会被中间人截获甚至替换掉,这样中间人就可以用截获的密钥解密报文,甚至替换掉密钥以达到篡改报文的目的。

有人说对这个密钥加密不就完了,但对方如果要解密这个密钥还是要传加密密钥给对方,依然还是会被中间人截获的,这么看来直接传输密钥无论怎样都无法摆脱俄罗斯套娃的难题,是不可行的。

2.非对称加密:解决单向对称密钥传输问题

直接传输密钥无论从哪一端传从上节分析来看是不行了,这里我们再看另一种加密方式:非对称加密。

非对称加密即加解密双方使用不同的密钥,一把作为公钥,可以公开的,一把作为私钥,不能公开,公钥加密的密文只有私钥可以解密,私钥加密(私钥签名)的内容,也只有公钥可以解密(公钥验签)

非对称加密安全性非常好,但加密和解密耗时较长,比较适用于小数据量加密解密。

这样的话对于 server 来说,保管好私钥,发布公钥给其他 client,其他 client 只要把对称加密的密钥加密传给 server 即可。

如此一来由于公钥加密只有私钥能解密,而私钥只有 server 有,所以能保证 client 向 server 传输是安全的,server 解密后即可拿到对称加密密钥,这样交换了密钥之后就可以用对称加密密钥通信了。

但是问题又来了, server 怎么把公钥安全地传输给 client 呢。如果直接传公钥,也会存在被中间人调包的风险。

3.数字证书,解决公钥传输信任问题

如何解决公钥传输问题呢,从现实生活中的场景找答案,员工入职时,企业一般会要求提供学历证明。

显然不是什么阿猫阿狗的本本都可称为学历,这个学历必须由第三方权威机构(Certificate Authority,简称 CA)即教育部颁发。

同理,server 也可以向 CA 申请证书,在证书中附上公钥(是指数字签名证书里的“站点的公开密钥”,即服务端公钥),然后将证书传给 client,证书由站点管理者向 CA 申请,申请的时候会提交 DNS 主机名等信息,CA 会根据这些信息生成证书。

这样当 client 拿到证书后,就可以获得证书上的公钥,再用此公钥加密对称加密密钥传给 server 即可,看起来确实很完美,不过在这里大家要考虑两个问题。

问题一:如何验证证书的真实性,如何防止证书被篡改

想象一下上文中我们提到的学历,企业如何认定你提供的学历证书是真是假呢?

答案是用学历编号,企业拿到证书后用学历编号在学信网上一查就知道证书真伪了,学历编号其实就是我们常说的数字签名,可以防止证书造假。

回到 HTTPS 上,证书的数字签名该如何产生的呢,一图胜千言:

(图中“第三方权威机构私钥”是指CA私钥)

证书的数字签名生成步骤如下:

①首先使用一些摘要算法(如 MD5)将证书明文(如证书序列号,DNS主机名等)生成摘要,然后再用第三方权威机构的私钥(CA私钥)对生成的摘要进行加密(签名)。

消息摘要是把任意长度的输入揉和而产生长度固定的伪随机输入的算法,无论输入的消息有多长,计算出来的消息摘要的长度总是固定的,加解密更快。

一般来说,只要内容不同,产生的摘要必然不同(相同的概率可以认为接近于 0),所以可以验证内容是否被篡改了。

为啥要先生成摘要再加密呢,不能直接加密?

因为使用非对称加密是非常耗时的,如果把整个证书内容都加密生成签名的话,客户端验签也需要把签名解密,证书明文较长,客户端验签就需要很长的时间。

而用摘要的话,会把内容很长的明文压缩成小得多的定长字符串,客户端验签的话就会快得多。

②客户端拿到证书后也用同样的摘要算法对证书明文计算摘要,两者一比对就可以发现报文是否被篡改了,那为啥要用第三方权威机构(Certificate Authority,简称 CA)私钥对摘要加密?

因为摘要算法是公开的,中间人可以替换掉证书明文,再根据证书上的摘要算法计算出摘要后把证书上的摘要也给替换掉!

这样 client 拿到证书后计算摘要发现一样,误以为此证书是合法就中招了。

所以必须要用 CA 的私钥给摘要进行加密生成签名,这样的话 client 得用 CA 的公钥(是指下文中的“内置 CA 证书中的公钥)来给签名解密,拿到的才是未经篡改合法的摘要(私钥签名,公钥才能解密)。

server 将证书传给 client 后,client 的验签过程如下:

(图中“第三方机构公钥”是指CA公钥)

这样的话,由于只有 CA 的公钥才能解密签名,如果客户端收到一个假的证书,使用 CA 的公钥是无法解密的,如果客户端收到了真的证书,但证书上的内容被篡改了,摘要比对不成功的话,客户端也会认定此证书非法。

细心的你一定发现了问题,CA 公钥如何安全地传输到 client?如果还是从 server 传输到 client,依然无法解决公钥被调包的风险。

实际上此CA公钥是存在于 CA 证书上,而此证书(也称 Root CA 证书)被操作系统信任,内置在操作系统上的,无需传输。

如果用的是  Mac 的同学,可以打开 keychain 查看一下,可以看到很多内置的被信任的证书。

server 传输 CA 颁发的证书,客户中收到证书后使用内置 CA 证书中的公钥来解密签名,验签即可,这样的话就解决了公钥传输过程中被调包的风险。

问题二:如何防止证书被调包

实际上任何站点都可以向第三方权威机构申请证书,中间人也不例外。

正常站点和中间人都可以向 CA 申请证书,获得认证的证书由于都是 CA 颁发的,所以都是合法的。

那么此时中间人是否可以在传输过程中将正常站点发给 client 的证书替换成自己的证书呢?

如下所示:

答案是不行,因为客户端除了通过验签的方式验证证书是否合法之外,还需要验证证书上的域名与自己的请求域名是否一致。

中间人中途虽然可以替换自己向 CA 申请的合法证书,但此证书中的域名与 client 请求的域名不一致,client 会认定为不通过!

但是上面的证书调包给了我们一种思路,什么思路?大家想想,HTTPS 既然是加密的,charles 这些「中间人」为啥能抓到明文的包呢,其实就是用了证书调包这一手法。

想想看,在用 charles 抓 HTTPS 的包之前我们先要做什么,当然是安装 charles 的证书:

这个证书里有 charles 的公钥,这样的话 charles 就可以将 server 传给 client 的证书调包成自己的证书。

client 拿到后就可以用你安装的 charles  证书来验签等,验证通过之后就会用 charles 证书中的公钥来加密对称密钥了。

整个流程如下:

由此可知,charles 这些中间人能抓取 HTTPS 包的前提是信任它们的 CA 证书,然后就可以通过替换证书的方式进行瞒天过海,所以我们千万不要随便信任第三方的证书,避免安全风险。

4.HTTPS中的数字证书和数字签名

部分资料来源于 数字签名与HTTPS详解 - 如.若 - 博客园

4.1 https 中数字证书和数字签名定义

https 证书及 SSL 证书,SSL 数字证书提供了 SSL 加密通道,这个 http 是没有办法保证的,因为 http 采用明文方式传输数据。

数字证书是由证书认证机构对证书申请者身份验证之后,用 CA 根证书对申请人的一些基本以及申请人的公钥进行签名,签名即 CA 私钥对服务端公钥以及证书序列号、DNS主机名等转换化后的 hash 值进行加密,将服务端公钥以及证书序列号、DNS主机名等和签名联合组成数字证书。CA 部门完成签发证书后会把证书发布在目录服务器中,任何人都可以查询和下载,数字证书含有 CA 认证过的公钥,私钥交由证书持有者在本地生成。证书是 CA 机构给服务端的,服务端的数字证书含有服务端公钥以及证书序列号、DNS主机名等加上 CA 私钥加密后的 Hash 值,这个 Hash 值是服务端公钥以及证书序列号、DNS主机名等转变后的 Hash 值,CA 私钥加密后的(Hash 值)就是数字签名

4.2 数字证书的生成过程以及验证机制

下面我们详细看一下当 https 服务器把公钥(含有服务端公钥的数字证书)交给客户端之前,数字证书是怎么生成的吧:

  1. 服务端人员使用RSA算法生成两个密钥,一个用来加密一个用来解密。将负责加密的那个密钥公布出去,所以我们称之为公钥(Public Key),而用来解密的那个密钥,不能对外公布,只有服务端持有,所以我们称之为私钥(Private Key)。服务端在将Public Key进行分发证书之前需要向CA机构申请给将要分发的公钥进行数字签名。(服务器公钥负责加密,服务器私钥负责解密)

  2. 生成数字签名公钥证书:对于CA机构来说,其也有两个密钥,我们暂且称之为CA私钥和CA公钥。CA机构将服务端的Public Key作为输入参数将其转换为一个特有的Hash值(与前文中“使用一些摘要算法(如 MD5)将证书明文(如证书序列号,DNS主机名等)生成摘要”有语义冲突!)。然后使用CA私钥将这个Hash值进行加密处理,并与服务端的Public Key绑定在一起,生成数字签名证书。其实数字签名证书的本质就是服务端的公钥+CA私钥加密的Hash值。(CA私钥负责签名,CA公钥负责验证)

  3. 服务器获取到这个已经含有数字签名并带有公钥的证书,将该证书发送给客户端。当客户端收到该公钥数字证书后,会验证其有效性。大部分客户端都会预装CA机构的公钥,也就是CA公钥。客户端使用CA公钥对数字证书上的签名进行验证,这个验证的过程就是使用CA公钥对CA私钥加密的内容进行解密,将解密后的内容与服务端的Public Key所生成的Hash值进行匹配,如果匹配成功,则说明该证书就是相应的服务端发过来的。否则就是非法证书。

第2种说法:

数字证书的构造与分发

参考资料:https://www.zhihu.com/question/61761633/answer/191126076

数字证书
CA公司的公钥以何种格式分发给每台电脑呢?
用自签名的方式,生成数字证书,一般格式:

谁是签发者:自己喽
公钥:1024/2048位公钥(明文)
有效期:xx
哈希算法:将公钥生成哈希
加密算法:将哈希用私钥加密,生成指纹
指纹:见上

又是如何安全可靠的分发出去的?
Windows操作系统预装

当你拿到一台崭新的电脑时,其实已经拥有了各大权威CA公司的自签名数字证书,也称为根证书,我一般称为公钥,因为只有公钥是真正干活的!

当你访问某台HTTPS服务器时,TLS连接过程中,对方出示了某CA公司的数字证书链,先从根证书开始层层校验,由于你已经拥有CA的公钥,可以解密对方指纹,你可以认证对方是真正的CA,既然CA合法,CA签发的第三方也是合法的,进而完成认证,完成TLS协商。

第3种说法:

参考资料:HTTPS 客户端验证 服务端证书流程_Super_jun的博客-CSDN博客

四、其他 HTTPS 相关问题

1.什么是双向认证

以上的讲述过程中,我们只是在 client 端验证了 server 传输证书的合法性,但 server 如何验证 client 的合法性,还是用证书,我们在网上进行转账等操作时,想想看是不是要先将银行发给我们的 U 盾插到电脑上?

其实也是因为 U 盾内置了证书,通信时将证书发给 server,server 验证通过之后即可开始通信。

画外音:身份认证只是 U 盾功能的一种,还有其他功能,比如加解密都是在 U 盾中执行,保证了密钥不会出现在内存中。

2.什么是证书信任链

前文说了,我们可以向 CA 申请证书,但全世界的顶级 CA(Root CA) 就那么几个,每天都有很多人要向它申请证书,它也忙不过来啊,怎么办呢?

想想看在一个公司里如果大家都找 CEO 办事,他是不是要疯了,那他能怎么办?

授权,他会把权力交给 CTO,CFO 等,这样你们只要找 CTO 之类的就行了,CTO 如果也忙不过来呢,继续往下授权啊。

同样的,既然顶级 CA 忙不过来,那它就向下一级,下下级 CA 授权即可,这样我们就只要找一级/二级/三级 CA 申请证书即可。

怎么证明这些证书被 Root CA 授权过了呢,小一点的 CA 可以让大一点的 CA 来签名认证。

比如一级 CA 让 Root CA 来签名认证,二级 CA 让一级 CA 来签名认证。

Root CA 没有人给他签名认证,只能自己证明自己了。这个证书就叫「自签名证书」或者「根证书」,我们必须信任它,不然证书信任链是走不下去的(这个根证书前文我们提过,其实是内置在操作系统中的)。

                                               证书信任链

现在我们看看如果站点申请的是二级 CA 颁发的证书,client 收到之后会如何验证这个证书呢,实际上 service 除了传给二级 CA 的证书外,还会把证书信任链也一起传给客户端。

这样客户端会按如下步骤进行验证:

  1. 浏览器就使用信任的根证书(根公钥)解析证书链的根证书得到一级证书的公钥+摘要验签。

  2. 拿一级证书的公钥解密一级证书,拿到二级证书的公钥和摘要验签。

  3. 再然后拿二级证书的公钥解密 server 传过来的二级证书,得到服务器的公钥和摘要验签,验证过程就结束了。

3.SSL/TLS握手过程

TLS是继承于SSL的。

参考:HTTPS通信原理-证书交换 - 苍青浪 - 博客园

TLS握手过程

握手简述(以RSA为例):

  • client hello:客户端给出TLS协议版本号,支持的加密算法、随机数Client random、扩展字段
  • server hello:服务端确认双方可支持的加密算法,并把数字证书下发给客户端。同时也会生成一个随机数Server random
  • 客户端验证证书的有效性,并重新生成一个随机数Pre-main secret,使用证书中的公钥加密随机数(此处即为非对称加密算法使用的地方),发送给服务端
  • 服务端使用私钥获取随机数
  • 客户端与服务端根据约定的加密算法,使用前面的三个随机数,生成对话密钥Session key,用来加密后续会话。

注:整个通信过程只会用到一次非对称加密算法(主要是用来传输客户端生成的用于对称加密的随机数密钥)。所以协商出来的对称密钥只有一个,每次通信都使用此对称密钥进行加解密。

存在两种说法:①非对称加密算法是加密了第三个随机数;②非对称加密算法是加密了对称密钥。

4.防重放攻击

参考:https能防重放吗_HTTPS如何防止重放攻击?_weixin_39588084的博客-CSDN博客

每个连接都会验证证书,交换密钥。即每个socket连接协商出唯一一个对称密钥。

客户端与服务器间通讯可以建立一个或多个socket连接,看情况而定。

别人就算截获你的数据包,重新发送一遍(中间人冒充客户端,它得跟服务器间创建一个socket连接,此socket与客户端的socket是不同的),因为socket不一样,密钥也就不一样,后台解密后应该是一堆乱码才对。所以https本身就是防止重放攻击的。
中间人拦截通讯结构图:

总结

相信大家看完本文应该对 HTTPS 的原理有了很清楚的认识了,HTTPS 无非就是 HTTP+SSL/TLS

而 SSL/TLS 的功能其实本质上是如何协商出安全的对称加密密钥以利用此密钥进行后续通讯的过程,带着这个疑问相信你不难理解数字证书和数字签名这两个让人费解的含义。

搞懂了这些也就明白了为啥 HTTPS 是加密的,charles 这些工具却能抓包出明文来。

深入理解HTTPS及其安全性问题相关推荐

  1. 轻松理解https,So easy!

    作者:翟志军 https://showme.codes/2017-02-20/understand-https/ 本文尝试一步步还原HTTPS的设计过程,以理解为什么HTTPS最终会是这副模样.但是这 ...

  2. 也许,这样理解 HTTPS 更容易

    本文尝试一步步还原HTTPS的设计过程,以理解为什么HTTPS最终会是这副模样.但是这并不代表HTTPS的真实设计过程.在阅读本文时,你可以尝试放下已有的对HTTPS的理解,这样更利于"还原 ...

  3. 也许,这样理解HTTPS更容易

    https://juejin.im/post/5b8367b1e51d453884361fc3 摘要: 本文尝试一步步还原HTTPS的设计过程,以理解为什么HTTPS最终会是这副模样.但是这并不代表H ...

  4. java-信息安全(九)-基于DH,非对称加密,对称加密等理解HTTPS

    概述 java-信息安全(七)-基于非对称加密,对称加密等理解HTTPS 如果想要理解好https,请尽量了解好以上信息等. 参看文章: http://www.ruanyifeng.com/blog/ ...

  5. 深入理解HTTPS及在iOS系统中适配HTTPS类型网络请求(上)

    2019独角兽企业重金招聘Python工程师标准>>> 深入理解HTTPS及在iOS系统中适配HTTPS类型网络请求 一.引言 本篇博客主要讨论如何在客户端与服务端之间进行HTTPS ...

  6. 一分钟理解 HTTPS 到底解决了什么问题

    本文原作者"虞大胆的叽叽喳喳",原文链接:jianshu.com/p/8861da5734ba,感谢原作者. 1.引言 很多人一提到 HTTPS,第一反应就是安全,对于普通用户来说 ...

  7. 用汽车拉苹果的例子来说HTTPS的安全性很容易理解 但HTTPS并不是绝对可靠的

    从2017年1月(Chrome56)开始, Google Chrome56将强制http标识为不安全 ,知乎上@车小胖 同学用一个汽车拉苹果的例子,很形象的说清楚了https与http的区别.虽然ht ...

  8. 一文读懂Https的安全性原理、数字证书、单项认证、双项认证等

    为什么80%的码农都做不了架构师?>>>    本文引用了作者Smily(博客:blog.csdn.net/qq_20521573)的文章内容,感谢无私分享. 1.前言 目前苹果公司 ...

  9. 也许,这样理解 HTTPS 更容易!

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 作者 | 翟志军 来源 | showme.codes/2 ...

最新文章

  1. AI一分钟 |“最抢手”毕业生排名出炉:清华没进前三?支付宝将支持iPhone X刷脸
  2. [置顶] Hibernate从入门到精通(十)多对多单向关联映射
  3. linux下的/dev/shm/ 以及与swap目录的区别【转】
  4. 如何在ASP.NET服务器控件库中嵌入JavaScript脚本文件 [适用于.NET 2.0]
  5. java_math_BigDecimal
  6. android 支付宝月账单 统计图_记账其实很简单,用微信、支付宝就够了!
  7. [复习计划]IMS5024
  8. [ Front-end ] Iframe 跨域双向通信
  9. Hi3516E V200功能介绍
  10. Android加载网络GIF完整解决方案
  11. 测试工具apipost postman jmeter
  12. linux 字幕制作工具,Arctime for Linux免费字幕软件
  13. 互联网公司的“江湖绰号”盘点,你知道几个?
  14. 苹果开发者中心添加UDID设备教程(及获取苹果手机的UDUD)
  15. Astalavista被蹂躏过程 转载自baoz net
  16. WINDOWS 耳机 有驱动 没声音
  17. matlab 判断矩阵是否正定
  18. 光滑曲线_使用Python实现贝塞尔曲线连接多点形成光滑曲线
  19. solidworks 32位计算机,SolidWorks2016
  20. android10获取WiFi名称 已经连接的WiFi名称 SSID

热门文章

  1. CorelDraw软件设计弧形文字的操作方法教学
  2. linux sockaddr结构体,linux网络编程笔记 sockaddr_in结构体[转]
  3. getchar与scanf的区别
  4. android红米3调用相机,手机拍照经验分享:用Redmi K30拍极光!
  5. c语言scanf输入丢失问题和分析
  6. 代购系统、代购源码、代购程序、电商API开发等
  7. 软件测试面试-自定义表单配置该如何测试?
  8. java打断sleep_Java中sleep()和wait()的区别
  9. c语言gaokao题目,史上最全!高考语文各题型满分答题攻略,高一高二高三的都看看!...
  10. element.style是css声明对象CSSStyleDeclaration