一、HTTPS 产生背景🐳

上过网的朋友都知道,网络是非常不安全的。尤其是公共场所很多免费的WIFI,或许只是攻击者的一个诱饵。还有大家平时喜欢用的万能钥匙,等等。那我们平时上网可能会存在哪些风险呢?

  1. 泄密,个人隐私、账户密码等信息可能会被盗取。
  2. 篡改,收到的数据可能被第三方修改过,或被植入广告等。
  3. 假冒,访问的站点非目标服务器站点。如域名欺骗、域名劫持、钓鱼网站等。

可能住你隔壁穿人字拖、说话都略显羞涩的小王,一到夜深人静的时候就开始偷窥你的一举一动!陪你一起看91某社区的电影还好,万一窃取了各购物网站或其他站点的登录信息就……是不是想想有些害怕呢!

xiaowang.jpg

为什么别人能获取你上网的数据呢?有过一定网络基础的朋友多少都对TCP/IP有些了解,对各种握手挥手早已背得滚瓜烂俗,对http协议也早了然于心。http是应用层的协议,位于TCP/IP参考模型的最上层。用户数据经过应用层、传输层、网络层、链路层的层层封装后经过物理层发送到目标机器。在这几层中,数据都没有经过加密处理,所以一旦别人获取到你的数据包,就能轻易的获取到数据的信息。

二、HTTPS 介绍🐋

HTTPS(全称:Hyper Text Transfer Protocol over SecureSocket Layer),是以安全为目标的 HTTP 通道,在HTTP的基础上通过传输加密和身份认证保证了传输过程的安全性。HTTPS 在HTTP 的基础下加入SSL,HTTPS 的安全基础是 SSL,因此加密的详细内容就需要 SSL。SSL(Secure Sockets Layer)中文叫“安全套接层”,后来由于广泛应用,SSL标准化之后就改名为TLS(Transport Layer Security)了。
众所周知,WEB服务存在http和https两种通信方式,http默认采用80作为通讯端口,对于传输采用不加密的方式;https默认采用443,对于传输的数据进行加密传输。目前主流的网站基本上开始默认采用HTTPS作为通信方式。HTTPS=HTTP+SSL,在HTTP层和TCP之间加了一个SSL/TLS层,如下图:

http.jpg

三、HTTPS 基础知识🐟

1、对称加密

duichen.png

HTTPS对称加密算法的加密和解密都是用同一个密钥。如果通信双方都各自持有同一个密钥,且没有别人知道,则两方的通信安全是可以被保证的(除非密钥被破解)。然而,最大的问题就是这个密钥怎么让传输的双方知晓,同时不被别人知道。如果由服务器生成一个密钥并传输给浏览器,这个传输过程中密钥被别人劫持,之后他就能用密钥解开双方传输的任何内容。
HTTPS如果浏览器内部预存了网站A的密钥,且可以确保除了浏览器和网站A,不会有任何外人知道该密钥,那理论上用对称加密是可以的。这样,浏览器只要预存好世界上所有HTTPS网站的密钥就可以了。显然,这样做是不现实的。
HTTPS怎么办?解决这个问题,我们就需要非对称加密。

2、非对称加密

feiduichen.png

基于对称加密存在的问题,又有了非对称加密。非对称加密算法需要一组密钥对,分别是公钥私钥,这两个密钥是成对出现的。公钥加密的内容需要对应的私钥解密,私钥加密的内容需要对应的公钥解密。私钥由服务器自己保存,公钥发送给客户端。客户端拿到公钥后可以对请求进行加密后发送给服务端,这时候就算中间被截获,没有私钥也无法解密发送的内容,这样确保了客户端发送到服务端数据的安全

3、非对称加密改良方案

gailiang.png

通过一组公钥私钥,已经可以保证单个方向传输的安全性,那用两组公钥私钥,是不是就能保证双向传输都安全了?请看下面的过程:

(1) 某网站拥有用于非对称加密的公钥A1、私钥A2;浏览器拥有用于非对称加密的公钥B1、私钥B2。

(2) 浏览器向网站服务器请求,服务器把公钥A1明文传输给浏览器。

(3) 浏览器把公钥B1明文传输给服务器。

(4) 之后浏览器向服务器传输的所有东西都用公钥A1加密,服务器收到后用私钥A2解密。由于只有服务器拥有私钥A2进行解密,所以能保证这条数据的安全。

(5) 服务器向浏览器传输的所有东西都用公钥B1加密,浏览器收到后用私钥B2解密。同上也可以保证这条数据的安全。

可见确实可行。抛开这里面仍有的漏洞不谈(下文会讲),HTTPS的加密却没使用这种方案,为什么?最主要的原因是非对称加密算法非常耗时,特别是加密解密一些较大数据的时候有些力不从心。而对称加密快很多。那我们能不能运用非对称加密的特性解决前面提到的对称加密的问题?

4、非对称加密 + 对称加密

fei_dui.png

既然非对称加密耗时,我们考虑是否可以采用非对称加密+对称加密结合的方式,而且要尽量减少非对称加密的次数。
非对称加密、解密各只需一次的方法:

(1) 某网站拥有用于非对称加密的公钥A1、私钥A2。

(2) 浏览器向网站服务器请求,服务器把公钥A1明文给传输浏览器。

(3) 浏览器随机生成一个用于对称加密的密钥X,用公钥A1加密后传给服务器。

(4) 服务器拿到后用私钥A2解密得到密钥X。

(5) 这样双方就都拥有密钥X了,且别人无法知道它。之后双方所有数据都用密钥X加密解密即可。

HTTPS基本就是采用了这种方案。但还是有漏洞的。

5、中间人攻击

midden.png

中间人的确无法得到浏览器生成的对称密钥X,这个密钥本身被公钥A1加密,只有服务器才能用私钥A2进行解密。然而中间人却完全不需要拿到私钥A2就能劫持信息,请看:

(1) 某网站拥有用于非对称加密的公钥A1、私钥A2。

(2) 浏览器向网站服务器请求,服务器把公钥A1明文传输给浏览器。

(3) 中间人劫持到公钥A1,保存下来,把数据包中的公钥A1替换成自己伪造的公钥B1(它当然也拥有公钥B1对应的私钥B2)。

(4) 浏览器随机生成一个用于对称加密的密钥X,用公钥B1(浏览器不知道公钥被替换了)加密后传给服务器。

(5) 中间人劫持后用私钥B2解密得到密钥X,再用公钥A1加密后传给服务器。

(6) 服务器拿到后用私钥A2解密得到密钥X。

这样在双方都不会发现异常的情况下,中间人得到了对称密钥X。根本原因是浏览器无法确认自己收到的公钥是不是网站自己的。那么下一步就是解决这个问题:如何证明浏览器收到的公钥一定是该网站的公钥?

6、数字证书

现实生活中,如果想证明某身份证号一定是小明的,怎么办?看身份证。这里政府机构起到了“公信”的作用,身份证是由它颁发的,它本身的权威可以对一个人的身份信息作出证明。互联网中也有这么一个公信机构,CA 机构。
网站在使用HTTPS前,需要向“CA机构”申请颁发一数字证书,数字证书里有证书持有者、证书持有者的公钥等信息。服务器把证书传输给浏览器,浏览器从证书里取公钥就可以了。

那这个数字证书怎么产生的呢?总不能是服务器自己造一个吧?上面说到了我们生活中的证书是由权威机构颁发的、无法伪造的,比如身份证就是由派出所发证、毕业证由教育部发证,如果需要验证真假,只需要上相关的系统输入编号查询就能查到了!那我们数字证书也应该有这两个特性-权威机构颁发、防伪

一个标准的数字证书(X.509数字证书)会包含以下内容:

(1) 版本信息

(2) 序列号 : 每个证书都有一个唯一的证书序列号;

(3) 签名算法 : 这个是CA机构在该证书中进行数字签名时所使用的加密算法,这样可以使用CA机构发布的证书里面的公钥,然后根据这个签名算法对指纹进行解密。指纹的加密结果就是CA机构使用自己私钥进行的数字签名。

(4) 签名哈希算法 : CA机构在进行数字签名之前,对证书的主体部分进行哈希计算,然后才对这哈希后的内容进行签名。

(5) 发行机构 : 说明时哪个CA机构发布这个证书。

(6) 证书有效期 : 如果过了有效期,证书作废,不能使用;

(7) 证书所有人 : 说明这个证书发布给谁,一般是个人、公司名称、机构名称或者网站地址等,例如我的个人博客:whbblog.cn就是证书的所有者。

(8) 证书所有人的公钥 : 这里是证书拥有者的公钥,也就是个人、公司、机构、网站等所有者的公钥。

(9) 认证机构的数字签名 : 这个是CA机构用私钥生成的签名,用于确保证书没有被篡改过。

7、CA机构

CA(Certification Authority)机构,就是数字证书颁发的权威机构,负责颁发证书以及验证证书的合法性

服务器向CA机构提交申请,需要提交站点的信息如域名、公司名称、公钥等等,CA审批无误之后就可以给服务器颁发证书了!此证书被 CA 进行了数字签名。任何用户都可从可信的地方获得认证中心 CA 的公钥,此公钥用来验证某个公钥是否为某个实体所拥有。有的大公司也提供认证中心服务。

数字证书的验证过程需要用到 CA根证书业务相关证书根证书 是预装在操作系统中的。在理解数字证书工作原理之前,我们需要先理解这两种证书是怎么生成的:

(1)CA根证书的生成

CA根证书生成.png

a. 权威机构利用RSA等算法,生成一对 公钥PK1 / 私钥SK1;

b. 将公钥PK1和证书发布机构、有效期等信息组成一份原始的证书内容,设为 C ;

c. 利用某种摘要算法,计算原始内容 C 的数字摘要,设为 H;

d. 用第一步生成的私钥SK1,对摘要H签名,得到签名内容S;

e. 将原始内容 C 和 签名内容 S 合在一起,就得到了根证书。

根证书安装在操作系统中,我们认为根证书是一定正确的。

(2)业务相关证书的生成

业务证书生成.png

a. 企业利用RSA等算法,生成一对 公钥PK2 / 私钥SK2;

b. 将 公钥PK2 和 证书其他内容 组成原始证书内容,设为C,给到CA权威机构;

c. 权威机构拿到 C 后,利用摘要算法,生成摘要信息 H;

d. 权威机构用自己的私钥SK1 (这是关键点),对摘要信息 H 签名,得到签名内容 S ;

e. 将 原始内容C 和 签名内容S 合并到一起,得到业务相关证书,交给企业。

**根证书和业务证书区别点在于:**业务申请的证书,在签名时用的私钥是CA机构的私钥。这个私钥是和根证书中的公钥对应的。

8、数字签名

我们把证书内容生成一份“签名”,比对证书内容和签名是否一致就能察觉是否被篡改。这种技术就叫数字签名。下图中左侧是数字签名的制作过程,右侧是验证过程。

签名.png

(1)发送方A数字签名的制作过程

  • 发送方A拥有非对称加密的私钥和公钥。

  • 发送方A对证书明文信息进行hash,得到信息摘要。

  • 发送方A用私钥对消息摘要加密,得到数字签名。

提问:

为什么对是对消息摘要进行加密签名?

对于较大文件而言,消息摘要即可将消息转换成简短的信息摘要,用以验证信息的完整性,还可压缩信息长度提高签名效率。

(2)接收方B数字签名的验证过程

  • 接收方B接受到消息及其签名后,用发送方A的公钥解密这个签名,获得由发送A生成的消息摘要。

  • 接收方B用发送方A所用的Hash算法重新生成所获得的消息的摘要。

  • 接收方B对比这两个摘要。如果相同,说明这个签名是发送方A针对这个消息的有效签名;如果不相同,则签名无效

提问:

制作数字签名时为什么需要hash一次
最显然的是性能问题,前面我们已经说了非对称加密效率较差,证书信息一般较长,比较耗时。而hash后得到的是固定长度的信息(比如用md5算法hash后可以得到固定的128位的值),这样加密解密就会快很多。当然除此之外也有安全上的原因。

HTTPS必须在每次请求中都要先在SSL/TLS层进行握手传输密钥吗?
显然每次请求都经历一次密钥传输过程非常耗时,那怎么达到只传输一次呢?用session就可以。服务器会为每个浏览器(或客户端软件)维护一个session ID,在TSL握手阶段传给浏览器,浏览器生成好密钥传给服务器后,服务器会把该密钥存到相应的session ID下,之后浏览器每次请求都会携带session ID,服务器会根据session ID找到相应的密钥并进行解密加密操作,这样就不必要每次重新制作、传输密钥了。

四、HTTPS 工作原理🐠

https原理.jpg

  1. 一般【客户端】首先发起请求,例如请求网站https://www.whbblog.cn/, 生成一个随机数(RandomC),携带支持的TLS版本、加密算法等信息发送至【服务端】。

  2. 【服务端】收到请求,返回证书、一个随机数(RandomS)、协商加密算法。

  3. 【客户端】拿到证书后开始进行校验,验证其合法性。客户端通过本地浏览器或操作系统内置的权威第三方认证机构的CA证书进行验证,一个证书包含域名、证书编号、公钥、有效期等信息,证书编号是在服务器管理员通过第三方证书机构申请证书的时候,第三方机构用他们的私钥对证书编号进行加密存入证书,根据编号生成方法生成证书编号(证书本身携带了生成证书编号的方法),与CA证书公钥解密得出的证书编号进行对比,验证不通过或者证书过期等情况就提示存在风险(浏览器的红色警告),验证通过则进行下一步。

  4. 【客户端】生成一个随机数(PreMaster Key),此时已经有第三个随机数了,根据三个随机数(RandomC、RandomS、PreMaster Key)按照双方约定的算法生成用于后面会话的同一把的“会话密钥”。

  5. 【客户端】将随机数(PreMaster Key)通过公钥加密后发送至【服务端】。

  6. 【服务端】收到密文后用私钥进行解密,得到随机数(PreMaster Key),此时服务端也拥有了三个随机数,根据三个随机数按照事先约定的加密算法生成用于后面会话的同一把的“会话密钥”。

  7. 【服务端】计算此前所有内容的握手消息hash值,并用“会话密钥”加密后发送至客户端用于验证。

  8. 【客户端】解密并计算握手消息的hash值,如果与服务端发来的hash一致,此时握手过程结束。

  9. 验证通过后,开始正常的加密通信。

五、参考链接🐙

感谢以下大佬文档支持!!!

🍅HTTPS 加密机制 - SXISZERO - 博客园 (cnblogs.com)

🥕看完这篇文章,我奶奶都懂了https的原理 (qq.com)

🍓科普 | 数字签名的概念及其原理 | 巴比特 (8btc.com)

🍉摘要、签名与数字证书都是什么? - 简书 (jianshu.com)

🍐图解HTTPS基本原理 - Thinktxt