HTTPS

更新:
我的文章只能当做参考,具体细节大家参考下这篇文章https://www.thesslstore.com/blog/explaining-ssl-handshake/


一、什么是HTTPS?

HTTPS = HTTP + TLS

二、什么是TLS?

TLS:(Transport Layer Security)传输层安全性协议,是 IETF 在 SSL3.0 的基础上设计的协议。
SSL:(Secure Socket Layer) 安全套接层,于 1994 年由网景公司设计,并于 1995 年发布了 3.0 版本。

三、什么是非对称加密?

同一个秘钥可以进行加密和解密称为对称加密,速度很快。而非对称加密则需要一对秘钥来完成加解密,即公钥和私钥。其中,公钥和私钥都可以用于加密和解密,即公钥加密->私钥解密,私钥加密->公钥解密。
非对称加密具有:防篡改,防抵赖,验证的特性。

  • 防篡改:由私钥加密的密文,必须经对应公钥解密,如果密文被修改,则公钥无法解密。
  • 防抵赖:如果私钥加密过的数据,使用者不承认 ,但是公钥却可以解密数据,则说明一定是对应私钥拥有者所为,因为仅有私钥加密的数据对应公钥可以解密。
  • 验证:非对称加密的特性,可以用来验证对方身份。公钥拥有者发送明文给私钥,私钥加密后发送给公钥,公钥再解密如果是刚才发送的明文,则可以验证对方身份。

四、数字签名

假设两个身份,A,B。
A先对原文进行MD5摘要,再对摘要使用私钥进行加密,最后将原文和摘要密文一起发送给B。
B拿到后,先使用公钥对摘要解密,再原文进行MD5摘要,最后比对一下两个摘要是否相同,以此来验证对方身份。
摘要加密得到的就是数字签名。
那为什么不直接使用原文加密来验证身份呢?
因为对原文进行加密的时间很长。原文加密时间 > 原文MD5摘要 + 摘要加密时间。

五、数字证书

  • 数字签名有什么问题吗?
    试想一下,如果不良人(不良人背锅)将用户公钥替换,再写个钓鱼网站,使用对应的私钥,这样就骗到用户了。
    所以只要保证公钥可信就行,那怎么保证呢? 可以先将公钥和摘要算法给到第三方权威机构,第三方机构再得到签名。签名和公钥,加密算法一起就是数字证书。因为对证书解密的公钥内置在浏览器或者操作系统内,所以就变得可靠了很多。
  • 什么是CA
  • 什么是CA证书
  • 什么是CFCA

六、HTTPS加密解密过程

握手阶段

TLS 1.2版本

这个截图来自https://www.thesslstore.com/blog/explaining-ssl-handshake/

这幅图包罗了HTTPS握手中可选和必选的所有步骤。
在这里插入图片描述
每个步骤可以抓包验证下,其中有些步骤是可选的,有可能抓不到。有的步骤可能和看到的不一致,比如第8步,Finashed,因为这个消息是第一个被加密的消息,在抓包时候实际上是这步:
在这里插入图片描述
同样,第10步,服务端的Finashed也一样。

下面我抓包将不同步骤标记出来,其中Client端使用绿色,Server端使用红色。
在这里插入图片描述

TLS1.3版本

在这里插入图片描述

1. 单向验证

1.1 客户端发起ClientHello
请求内容包括:

  • 客户端支持的SSL/TLS协议列表
  • 客户端支持的对称加密算法
  • 随机数A

1.2 是服务端回应ServerHello

  • SSL/TLS版本。选择双方支持的SSL/TLS最高版本。如果客户端支持的版本服务器端不支持则拒绝访问。
  • 对称加密算法。选择客户端支持的最安全版本。
  • 秘钥库中取出的证书。
  • 随机数B

1.3 客户端回应

  • pre-master key。客户端需要先检查证书,检查通过后根据特定方法生成一个随机数C,这个随机数被称为:“pre-master key”。客户端再使用刚才的公钥加密随机数C发送。

1.4 服务器最后回应

  • 服务器回应客户端,握手结束。服务器端使用私钥解密得到随机数C,服务器端和客户端此时都拥有随机数A,B,C,双方使用DH秘钥交换算法得到相同的对称加密的秘钥,用于后续通讯。

要点:

  • 为什么要使用三个随机数:客户端和服务端都不能保证自己的随机数是真正随机生成的,这样会导致数据传输使用的密钥就不是随机的,时间长了,就很容易被破解。如果使用客户端随机数、服务端随机数、pre-master key随机数这3个组合,就能十分接近随机。
  • 中间人攻击问题:客户端是验证有问题的时候,是可以选择继续的。对浏览器而言,用户可以选择继续访问;对程序而言,有些系统为了处理简单,会选择信任所有证书,这样就给中间人攻击提供了漏洞。中间人攻击时,它想办法拦截到客户端与服务器之间的通信。在客户端向服务器发信息时,中间人首先伪装成客户端,向真正的服务器发消息,获得真正的证书,接着伪装成服务器将自己的伪证书发给客户端。服务器向客户端发消息时,中间人伪装成客户端,接收消息,然后再伪装成服务器向客户端发消息。最后验证过程完成后,客户端的真实对称密钥被中间人拿到,而真正的服务器拿到的是中间人提供的伪密钥。后续数据传输过程中的数据就会被中间人窃取。

2.双向验证

2.1 使用双向验证或者是单向验证都是由服务器决定的。一般服务器都是默认单向验证,可以在服务器端配置双向验证。比如Tomcat:

设置为true则开启双向验证。
2.2 双向验证与单向验证不同的地方:

  • 第二步服务器向客户端回应serverHello时,除了单向验证的那些东西,还需要客户端提供“客户端的证书”。

  • 第三部客户端验证完服务器端的证书后,会回应:

    1)客户端的证书
    2)客户端证书验证消息(CertificateVerify message):客户端将之前所有收到的和发送的消息组合起来,并用hash算法得到一个hash值,然后用客户端密钥库的私钥对这个hash进行签名,这个签名就是CertificateVerify message

2.3 服务器收到客户端证书后:

  • 确认这个证书是否在自己的信任库中(当然也会校验是否过期等信息),如果验证不通过则会拒绝连接;
  • 用客户端证书中的公钥去验证收到的证书验证消息中的签名。这一步的作用是为了确认证书确实是客户端的。

所以,在双向验证中,客户端需要用到密钥库,保存自己的私钥和证书,并且证书需要提前发给服务器,由服务器放到它的信任库中。

3. 总结

1、单向验证中,如果是你客户端,你需要拿到服务器的证书,并放到你的信任库中;如果是服务端,你要生成私钥和证书,并将这两个放到你的密钥库中,并且将证书发给所有客户端。
ps:什么是信任库和密钥库?
    信任库是用来存放信任的CA的证书。在程序交互中,需要确保你访问的服务器的证书在你的信任库里面。如果收到的证书签发机构不在信任库中,则客户端会提示用户证书不可信。
    密钥库是用来存放服务器的私钥和证书。

2、双向验证中,如果你是客户端,你要生成客户端的私钥和证书,将它们放到密钥库中,并将证书发给服务端,同时,在信任库中导入服务端的证书。如果你是服务端,除了在密钥库中保存服务器的私钥和证书,还要在信任库中导入客户端的证书。

3、使用单向验证还是双向验证,是服务器决定的。

参考:

[1]coding涛:HTTPS实战之单向验证和双向验证
[2]web前端开发:前端都看得懂的https的加密解密
[3]极客时间:透视HTTP协议

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 技术工厂 设计师:CSDN官方博客 返回首页