一次完整的HTPPS请求

文章目录

  • 第一次http请求443端口
    • 第一次数据发送:客户端发起
    • 第二次数据发送:服务器发起
    • 第三次数据发送:客户端发起
    • 第四次数据发送:服务端发起
  • 第二次http请求
  • https的本质

首先我们知道,http是基于TCL/IP协议。
在http的基础上,在TCP/IP与http中间加一层SSL加密协议,就变成了HTTP over SSL,简称https。
一次完整的https请求,其实是由两次http请求构成的

第一次http请求443端口

HTTPS工作在443端口,所以第一次http请求443端口
这次请求的主要目的,是约定客户端和服务端的加密方式和秘钥,如下图
一次完整的HTPPS请求_第1张图片
从图中我们已经大致看出,客户端和服务端一共进行了4次数据发送,最多13个数据包。

第一次数据发送:客户端发起

数据包1:CilentHello
本次请求,客户端携带了客户端随机数random1、会话ID(SessionID)、客户端支持的加密套件等信息。如果是第一次请求,则sessionID为空

第二次数据发送:服务器发起

数据包2:ServerHello
服务器接收到客户端请求后,在本数据包发送服务端随机数random2、服务器端生成的sessionID、服务器从客户端支持的加密套件中选定的一个套件。

如果非第一次请求的话,且服务端验证客户端发送的sessionID有效,根据sessionID获取加密秘钥后,直接跳过之后的数据发送步骤,从数据包12开始。13请求结束后,客户端发起一次change cipher spec 和 finished请求,用于确认加密方式和验证秘钥,之后第一次http请求结束。

数据包3:Certificate
服务器证书

数据包4:Sever Key Exchange
根据数据包1中的加密套件,决定了密钥交换方式(例如RSA或者DH),因此在Server Key Exchange消息中便会包含完成密钥交换所需的一系列参数:ssl加密方式、服务端公钥等

数据包5:Certificate Request(可选,默认为单向认证)
证书验证方式,单向认证或双向认证
如果是双向认证,该消息中包含服务器端支持的证书类型(RSA、DSA、ECDSA等)和服务器端所信任的所有证书发行机构的CA列表,客户端会用这些信息来筛选证书。客户端在下次数据发送时,需要携带证书信息

数据包6:Server Hello Done
告知客户端本次数据发送结束

第三次数据发送:客户端发起

数据包7:Certificate(可选)
如果数据包5发送了双向验证请求,该数据包会发送客户端持有的证书到服务端。客户端在发送证书前,会根据数据包5中接收到的信息,对要发送的证书进行初步的筛选和验证。
至于具体验证过程,现在还不是很明确。猜测应该是根据公钥解析出证书的信息,然后和数包5发送的信息进行对比。这个过程中用到了openssl组件,如果证书使用老版本的openssl组件生成的话,新版openssl1.1已经不在支持老版本中的MD5加密方式,导致报错:could not load PEM client certificate, OpenSSL error error:140AB18E:SSL routines:SSL_CTX_use_certificate:ca md too weak
此时,要么降低openssl版本兼容老版证书,要么使用新版openssl生成新的证书

数据包8:Client Key exchange
客户端发送秘钥交换数据
客户端先生成一个随机数(对称秘钥种子),然后根据数据包4中传递的服务端的证书中获取的公钥,和指定的加密方式(一般是RAS非对称加密),生成一个pre-master-secret(预主密码),把预主密码发送给客户端

数据包9:Certificate verify(可选)
客户端证书验证参数,双向验证时有该参数
其中包含一个签名,对从第一条消息以来的所有握手消息的HMAC值,用main_secret(主密码)进行签名。
main-secret是通过特定算法,传入random1,random2,pre-master-secret参数得到的

数据包10:ChangeCipherSpec
编码改变通知
表示随后的信息都将用双方商定的加密方法和密钥发送(ChangeCipherSpec是一个独立的协议,体现在数据包中就是一个字节的数据,用于告知服务端,客户端已经切换到数据包2协商好的加密套件(Cipher Suite)的状态,准备使用协商好的加密套件加main-secret进行对称加密传输了)

数据包11:Finished
客户端握手结束通知
表示客户端的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供服务器校验(使用HMAC算法计算收到和发送的所有握手消息的摘要,然后通过RFC5246中定义的一个伪函数PRF计算出结果,加密后发送。此数据是为了在正式传输应用数据之前对刚刚握手建立起来的加解密通道进行验证。)

第四次数据发送:服务端发起

数据包12:ChangeCipherSpec
编码改变通知

数据包13:Finished
服务端握手结束通知
该数据包发送前,做了如下事情:
1、接收到数据包8发送的pre-master-secret,使用本地的私钥解密pre-master-secret,证明自己持有客户端验证证书的私钥。失败则终止请求
2、使用pre-master-secret和random1和random2生成main-sectet
3、如果非首次链接,用 Session Secret 加密一段 Finish 消息发送给客户端,以验证之前通过握手建立起来的加解密通道是否成功

第二次http请求

本次http请求为正常的web请求。根据第一次http请求协商好的秘钥和加密方式,发送和接收数据。

https的本质

通过第一次http请求我们发现,做了这么多事,最后是为了让客户端和服务端商定一个公用的秘钥,又来发送和解密数据。

如果没有第一次请求商定秘钥,我们直接在http中传递秘钥,弊端是显而易见的,秘钥直接就暴露在了请求的数据中。那如果我们不使用对称加密,而是用非对称加密呢
比如:
A请求B,AB先彼此交换public_key,A发送数据时,用B的公钥加密,B收到后,用自己的私钥解密,私钥没有暴露在,看起来非常安全。但如果在AB交换public_key时,C劫持了他们的公钥,把自己的公钥发送给了AB。AB加密数据时,使用了C的公钥,C劫持到数据后,用自己的私钥解密并修改数据后,再使用C的public_key加密后发送给AB,数据安全还是无法保证。

https的本质就是:把公钥的交换过程从AB双方直接交换,改为通过一个中间人交换,这个中间人就是证书CA(Certificate Authority)
CA也是基于非对称加密算法来工作。有了CA,A会先把自己的public key(和一些其他信息)交给CA。CA用自己的private key加密这些数据,加密完的数据称为A的数字证书。现在A要向B传递public key,A传递的是CA加密之后的数字证书。B收到以后,会通过CA发布的CA证书(包含了CA的public key),来解密A的数字证书,从而获得A的public key。

而CA会把自己的证书集成到了浏览器和操作系统中,所以不用担心中间网络的劫持。

参考文章:
https://blog.csdn.net/qq_38265137/article/details/90112705
https://zhuanlan.zhihu.com/p/36981565

你可能感兴趣的:(后端,https,ca证书)