HTTPS通信详解

时间:2024-03-19 21:41:48

1. 密码学的基础知识

加密算法大致上分为两类:

  • 不基于key的加密算法。举个简单的例子,我要加密“fordesign”这么一串字符,就把每个字符都变成它的后一个字符,那么就是“gpseftjhm”了,这样的东西人家当然看不明白,接收方用相反的方法就可以得到原文。
  • 基于key的加密算法。现在的算法基本都是基于key的,key就是一串随机数,更换了key之后,算法还可以继续使用。基于key的加密算法又分为两类:
    • 对称加密。比如DES,AES,通信双方一方用key加密之后,另一方用相同的key进行反向的运算就可以解密。
    • 非对称加密。不对称加密比较著名的就是RSA,加密的时候有一个公钥和一个私钥,公钥是可以交给对方的,a给b发送信息,a用自己的私钥加密,b用a的公钥解密,反之,b给a发送信息,b用自己的私钥加密。

非对称加密算法在通信之前,需要经过一些握手的过程,双方交换公钥,这个就是key exchange的过程,https最开始的阶段就包含了这个key exchange的过程,大概原理是这样,有些地方还要稍微复杂一些。

实际操作中,单纯使用对称加密或单纯使用非对称加密都会存在一些问题,比如对称加密的**管理复杂;非对称加密的处理性能低、资源占用高等;有时会结合利用这两种算法,如HTTPS。

2. 网络安全问题

日常生活中,我们上网用的最多的应用层协议就是HTTP协议了,直至目前全世界的网站中大多数依然只支持HTTP访问。不过HTTP不使用SSL/TLS进行加密通信,所有信息明文传播,带来了三大风险:
(1) 窃听风险(eavesdropping):第三方可以获知通信内容。
(2) 篡改风险(tampering):第三方可以修改通信内容。
(3) 冒充风险(pretending):第三方可以冒充他人身份参与通信。

2.1 网络安全问题的解决思路

SSL/TLS协议是为了解决以上三大风险而设计的,希望达到:
(1) 所有信息都是加密传播,第三方无法窃听。
(2) 具有校验机制,一旦被篡改,通信双方会立刻发现。
(3) 配备身份证书,防止身份被冒充。

2.1.1 如何保证数据的机密性(不被窃听)

数据机密性解决思路–利用对称加密算法解决机密性

为了保证数据的机密性,首先可以采用的方法就是将数据通过相应加密算法,转换为其它的数据信息,然后再通过相应算法反推出真正的数据是什么,这样一来就保证了数据在网络传输过程中安全性,不会被其它人轻易的看到传输过程中的数据信息.数据加密前的信息称为明文数据(plaintext),经过加密算法转换后进行传输的信息称为密文数据(ciphertext);反之经过解密算法转换后,会将密文数据恢复为明文数据进行显示接收。
HTTPS通信详解

小结: 单纯的数据加密只能保证数据不被泄露,但不能保证接收方收到的数据的真实性(真实数据没有被篡改+数据是从真实发送者发来的)

2.1.2 如何保证数据的完整(不被篡改)

数据完整性解决思路–利用数据特征码

利用提取数据特征码的方式,完成数据传输的完整性验证。实际的算法实现过程为:给一段明文数据加上数据信息的特征码,这个特征码是通过结合数据信息进行相应算法获得的数据特征码,接收方当收到数据信息后,会利用相同的算法对获取的数据计算特征码,确认得到的特征码是否与传送过来的描述数据的特征码一致;如果一致,可以表示数据没有被篡改过,如果不一致表示数据完整性遭到了破坏,数据一概不予以接收处理。
HTTPS通信详解

数据完整性解决思路–利用数据特征码(加密特征码)

由于可能存在中间人攻击(篡改数据、特征码)的可能性,因此可以对传输过程中数据特征码进行加密,发送方利用对称**方式对手中的特征码进行加密,接收方会利用相同的**对手中的特征码进行解密,从而确认特征码是否一致。如果中间人将新的特征码也进行了加密,发送给接收方,但接收方无法利用和发送方协商好的解***对特征码进行解密,最终无法识别中间人发送过来的数据特征码信息。
HTTPS通信详解

  1. 在此需要了解一下加密算法的原理 ↓
    通讯双方需要进行数据**信息约定(**协商过程),在**相互可以获悉的过程中,需要借助**交换机制(Internet key exchange IKE),进而实现**的交互。为了满足网络中,两台主机间**交换统一的过程,需要引入一种新的协议diffie-hellman协议。
  2. diffie-hellman协议算法实现的过程:
    1)首先发送方选取一个大素数P(只能被1和自己整除的数),再选取一个生产数g ,并且发送方将P与g经过互联网传输到接收方。
    2)数据传输的两端,发送方选取一个随机数x,接收方选取一个随机数y;发送方只知道随机数x ,接收方只知道随机数y , x和y不在互联网上进行传输。
    3)接收数据双方开始进行计算,对于发送方进行计算g的x次方对P取模的结果,传输给接收者;而接收方进行计算g的y次方对P取模的结果,传输给发送者。
    4)此时对于接收方获取到了发送方的g的x次方对P取模的结果,在取模结果的基础上进行y次方的运算,y就是接收方自身产生的随机数y;而对于发送方获取到了接收方的g的y次方对P取模的结果,在取模结果的基础上进行x次方的运算。x就是发送方自身产生的随机数x#此次,双方的加密运算**就实现了交换,并且是统一一致的,最终的**为g的xy次方对P取模的结果。
    HTTPS通信详解
    通过diffie-hellman协议算法最终可以实现了网络传输双方的**交换,并且通讯的双方也从此不用再对**进行管理记忆,只需要在进行传输数据前,逬行一次**的交换过程;即完成了对称**的生成过程。
    并且如果网络中有攻击者在尝试**出交换**时,就算通过比较复杂的数学运算,获悉了**,但也只是了解了上一次的数据交换**信息;下一次数据传输双方通讯时,还会交换新的**用于新的数据传输。

小结: 通过加密特征码可以保证真实数据没有被篡改。

2.1.3 如何进行传输双方身份验证

网络安全身份验证解决方案

以上信息只是解决数据的交换获取问题,但是网络的身份验证问题依旧没有逬行解决,换句话说,通讯双方的确可以获取统一的加密信息了,并且是通过相对安全的方式获取得知的,但是通讯双方在交换获取**前,又怎么确认得知,交换密文的对方的确是要逬行通讯的发送方或接收方呢?

安全身份验证解决思路-利用非对称**加密算法

利用非对称加密算法,可以从根本上有效解决网络中,数据传输双方的安全身份验证问题。非对称加密算法中,存在**对的概念,即拥有公钥(public key)与私钥(private key),其中公钥不是自行创建出来的而是从私钥中提取出来一部分作为公钥,因此可以说公钥是来自于私钥的,而私钥才决定了**加密的安全性,于是私钥的长度可能会非常长,从最初的1024,2048,到4096一直到更多的位数,将私钥**位增加的很长,从而提升了**安全性。

利用非对称加密算法,需要遵循一个基本原则:公钥加密的只能利用与之配对的私钥进行解密,反之也是一祥的。非对称加密算法完全可以满足数据传输过程中对传输者身份验证的需求,因为接收者可以拥有相应的公钥,只有与之对应的发送者用相应的私钥进行加密信息,用对应的公钥方可解密,否则可以确认发送者身份已经发生了变化。
HTTPS通信详解

2.2 数字证书

2.2.1 数字证书的由来

2.1.3通过公钥加密算法解决了数据传输过程进行传输双方身份验证的问题,但是公钥在网络传递的过程也是会出现如下图所示的问题:
HTTPS通信详解

也就是说我们需要一种机制可以识别公钥发送方的真实性。这就是数字证书的由来。

对发送方的公钥信息进行认证步骤(借助第三方安全机构):

  1. A和B端首先生成自己的公钥和私钥的**对,为了使对方能相信自己的公钥信息,将自己的公钥信息告知给第三方发证机构,利用第三方机构对自己的公钥进行公证,第三方机构会制作一个数字证书(机构编号以及发证机构的联),并且第三方机构也要给自己设置一个合法的公钥和私钥,并且公钥设为第三方机构的公钥证书。
  2. 发证机关计算出数字证书数据的特征码,并用自己的私钥进行加密,并将加密的信息附加到特征码后成为数字签名。
  3. A和B两端获得公证过的证书信息,并通过证书信息传递.得到对方的公钥。
  4. A和B两端与第三方机构建立连接,获得第三方证书,通过第三方证书获得第三方公钥,利用第三方公钥只要能解密数字签名即可。

数字证书相当于是服务器的一个“身份证”,用于唯一标识一个服务器。

2.2.2 数字证书的签发

数字证书的组成

目前互联网上使用的SSL和TLS证书管理机制均使用x509的格式,还有其他的证书格式。

数字证书(如server.crt)由两部分组成:

  • C证书相关信息

    • 服务器公钥信息以及证书过期时间
    • 证书的合法拥有人信息
    • 证书该如何被使用
    • 证书颁发者(CA)信息
    • 证书签名算法
    • 证书签名的校验码
  • S证书的数字签名 (由CA证书通过加密算法生成的)

其中的数字签名是通过以下公式得到的:S=F(Digest(C))S = F(Digest(C))

Digest为摘要函数,是对证书相关信息做的一个摘要。摘要就是利用 md5、sha-1或sha256等单向散列算法,将无限输入值转换为一个有限长度的“浓缩”输出值。比如我们常用md5值来验证下载的大文件是否完整。大文件的内容就是一个无限输入。大文件被放在网站上用于下载时,网站会对大文件做一次md5计算,得出一个128bit的值作为大文件的摘要一同放在网站上。用户在下载文件后,对下载后的文件再进行一次本地的md5计算,用得出的值与网站上的md5值进行比较,如果一致,则大 文件下载完好,否则下载过程大文件内容有损坏或源文件被篡改。这个小技巧常常在机器之间copy或者下载压缩文件的时候也可以用md5sum的命令来进行检验,看看文件是否完整。

F为签名函数,CA自己的私钥(ca.key)是唯一标识CA签名的,因此CA用于生成数字证书的签名函数一定要以自己的私钥(ca.key)作为一个输入参数。在RSA加密系统中,发送端的解密函数就是一个以私钥作为参数的函数,因此常常被用作签名函数使用。因此CA用私钥解密函数作为F,以CA证书中的私钥(ca.key)进行加密,生成最后的数字签名。正如最后一部分实践时候给出的证书生成过程,生成server.crt的时候需要ca.crt(包含根证书的信息和根证书的公钥)和ca.key(根证书的私钥)都加入进去。

根CA证书(ca.crt)

一般而言,数字证书是从受信的权威证书授权机构 (Certification Authority,简称CA)买来的,浏览器里面一般就内置好了一些权威的CA,在使用https的时候,只要是这些CA签发的证书,浏览器都是可以认证的,要是在与服务器通信的时候,收到一个没有权威CA认证的证书,就会报出提醒不受信任证书的错误,就像登录12306一样,但是也可以选择接受。

在自己的项目中,通常是自己签发一个ca根证书(ca.crt,内含ca公钥),之后使用这个根证书签发一个服务端的数字证书server.crt和服务端的私钥server.key给服务端;在客户端和服务端通信的时候*(特别是使用代码编写的客户端访问的时候)*,要指定ca根证书,作用就相当于是浏览器中内置的那些权威证书一样,用于进行服务端的身份检。

2.2.3 客户端的处理

验证数字签名

客户端接收到服务端数字证书后,如何验证数字证书上携带的签名是这个CA签出来的呢?当然接收端首先需要指定对应的CA,接收端会运用下面算法对数字证书的签名进行校验:

F(S)?=Digest(C)F'(S) ?= Digest(C)

接收端进行两个计算,并将计算结果进行比对:

  1. 首先通过Digest(C),接收端计算出证书内容(除数字签名之外)的摘要,C的内容都是明文可以看到到的。

  2. 数字证书携带的数字签名是CA通过CA私钥(ca.key)加密摘要后的结果,因此接收端通过一个解密函数F’对S进行“解密”。就像最开始介绍的那样,在RSA系统中,接收端使用CA公钥(包含在ca.crt中)对S进行“解密”,这恰是CA用私钥对S进行“加密”的逆过程。

将上述两个运算的结果进行比较,如果一致,说明签名的确来自该CA,该证书有效,否则要么证书不是该CA的,要么就是中途被人篡改了。

对于self-signed(自签发)证书来说,接收端并没有你这个self-CA的数字证书(ca.crt),也就是没有CA公钥,也就没有办法对数字证书的签名进行验证。因此如果要编写一个可以对self-signed证书进行校验的接收端程序的话,首先我们要做的就是建立一个属于自己的CA,用该CA签发我们的server端证书,之后给客户端发送信息的话,需要对这个根证书进行指定,之后按上面的方式进行验证。

提取公钥

数字签名验证验证通过后,客户端就可以提取出数字证书相关信息中的公钥进行数据通信了。

3 HTTPS通信过程详解

HTTPS通信过程结合了对称加密和非对称加密两种方法。HTTPS服务端在连接建立过程(ssl shaking握手协议)中,会将自身的公钥发送给客户端。客户端拿到公钥后,通过非对称加密与服务端协商数据传输通道的对称加***(会话**)。一旦双方协商出会话**,则后续的数据通讯就会一直使用基于该会话**的对称加密算法了。

3.1 主要过程

SSL/TLS协议的基本思路是采用非对称加密法,也就是说,客户端先向服务器端索要公钥,然后用公钥加密信息,服务器收到密文后,用自己的私钥解密。

但是,这里有两个问题。

(1)如何保证公钥不被篡改?
解决方法:将公钥放在数字证书中。只要证书是可信的,公钥就是可信的。

(2)公钥加密计算量太大,如何减少耗用的时间?
解决方法:每一次对话(session),客户端和服务器端都生成一个"对话**"(session key),用它来加密信息。由于"对话**"是对称加密,所以运算速度非常快,而服务器公钥只用于加密"对话**"本身,这样就减少了加密运算的消耗时间。

因此,SSL/TLS协议的基本过程是这样的:
(1) 客户端向服务器端索要并验证公钥。
(2) 双方协商生成"对话**"。
(3) 双方采用"对话**"进行加密通信。

上面过程的前两步,又称为"握手阶段"(handshake),"握手阶段"涉及四次通信。需要注意的是,"握手阶段"的所有通信都是明文的。

3.1.1 握手阶段详解

握手阶段如下图所示:
HTTPS通信详解

1.客户端发出请求(ClientHello)

首先,客户端(通常是浏览器)先向服务器发出加密通信的请求,这被叫做ClientHello请求。

在这一步,客户端主要向服务器提供以下信息:

(1) 支持的协议版本,比如TLS 1.0版。
(2) 一个客户端生成的随机数a,稍后用于生成"对话**"。
(3) 支持的加密方法,比如RSA公钥加密。
(4) 支持的压缩方法。

这里需要注意的是,客户端发送的信息之中不包括服务器的域名。也就是说,理论上服务器只能包含一个网站,否则会分不清应该向客户端提供哪一个网站的数字证书。这就是为什么通常一台服务器只能有一张数字证书的原因。对于虚拟主机的用户来说,这当然很不方便。2006年,TLS协议加入了一个Server Name Indication扩展,允许客户端向服务器提供它所请求的域名。

2.服务器回应(SeverHello)

服务器收到客户端请求后,向客户端发出回应,这叫做SeverHello。服务器的回应包含以下内容。

(1) 确认使用的加密通信协议版本,比如TLS 1.0版本。如果浏览器与服务器支持的版本不一致,服务器关闭加密通信。
(2) 一个服务器生成的随机数b,稍后用于生成"对话**"。
(3) 确认使用的加密方法,比如RSA公钥加密。
(4) 服务器证书。

除了上面这些信息,如果服务器需要确认客户端的身份,就会再包含一项请求,要求客户端提供"客户端证书"。比如,金融机构往往只允许认证客户连入自己的网络,就会向正式客户提供USB**,里面就包含了一张客户端证书。

3.客户端回应

客户端收到服务器回应以后,首先验证服务器证书。如果证书不是可信机构颁布、或者证书中的域名与实际域名不一致、或者证书已经过期,就会向访问者显示一个警告,由其选择是否还要继续通信。

如果证书没有问题,客户端就会从证书中取出服务器的公钥。然后,向服务器发送下面三项信息。

(1) 一个随机数c。该随机数用服务器公钥加密,防止被窃听。
(2) 编码改变通知,表示随后的信息都将用双方商定的加密方法和**发送。
(3) 客户端握手结束通知,表示客户端的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供服务器校验。

  1. 上面第一项的随机数c,是整个握手阶段出现的第三个随机数,又称"pre-master key"。有了它以后,客户端和服务器就同时有了三个随机数,接着双方就用事先商定的加密方法,各自生成本次会话所用的同一把"会话**"。
  2. 至于为什么一定要用三个随机数,来生成"会话**",dog250解释得很好:
    “不管是客户端还是服务器,都需要随机数,这样生成的**才不会每次都一样。由于SSL协议中证书是静态的,因此十分有必要引入一种随机因素来保证协商出来的**的随机性。
    对于RSA**交换算法来说,pre-master-key本身就是一个随机数,再加上hello消息中的随机,三个随机数通过一个**导出器最终导出一个对称**。pre master的存在在于SSL协议不信任每个主机都能产生完全随机的随机数,如果随机数不随机,那么pre master secret就有可能被猜出来,那么仅使用pre master secret作为**就不合适了,因此必须引入新的随机因素,那么客户端和服务器加上pre master secret三个随机数一同生成的**就不容易被猜出了,一个伪随机可能完全不随机,可是是三个伪随机就十分接近随机了,每增加一个*度,随机性增加的可不是一。”
  3. 此外,如果前一步,服务器要求客户端证书,客户端会在这一步发送证书及相关信息。

4.服务器的最后回应

服务器收到客户端的第三个随机数pre-master key之后,计算生成本次会话所用的"会话**"。然后,向客户端最后发送下面信息。

(1)编码改变通知,表示随后的信息都将用双方商定的加密方法和**发送。
(2)服务器握手结束通知,表示服务器的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供客户端校验。

至此,整个握手阶段全部结束。接下来,客户端与服务器进入加密通信,就完全是使用普通的HTTP协议,只不过用"会话**"加密内容。

3.2 wireshark抓包分析

结合wireshark抓包分析验证HTTPS协议交互详细过程如下:

1.客户端首先向服务器端发送一个 Client Hello 的 SSL 握手信息
如下图所示:
HTTPS通信详解
其消息体如下所示:
HTTPS通信详解
消息体里面包含了下面的一些主要信息:
(1)Handshake Type:Client Hello(握手类型)。
(2)Random(随机数a)和一个时间戳:
HTTPS通信详解
(3)客户端支持的加密协议套件。说明client所支持的加密套件。用来告诉 HTTPS 的服务器端,客户端能支持这 26 种加密协议套装上列出的算法,让服务器选择一个加密协议算法套件:
HTTPS通信详解
(4)客户端访问的 Web 服务器的信息:
HTTPS通信详解
(5)客户端支持的签名算法:
HTTPS通信详解
客户端告诉服务器其支持 9 种签名算法,让服务器端*选择一个用于后续的加密通信。

2.HTTPS 服务器马上给客户端回复了下面这 4 条 SSL 握手信息

  • Server Hello
  • Certificate
  • Server Key Exchange Server
  • Hello Done

如图所示:
HTTPS通信详解

下面具体来看这 4 条由 HTTPS 服务器端发出的 4 条消息里面到底有什么内容,其会告诉客户端什么秘密和信息呢?

(1)Server Hello SSL 握手信息
HTTPS通信详解
发送随机数b,而且还生成了服务器端的 Session ID 并发送给客户端,最后告诉客户端,服务器端准备选择TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384作为秘钥交互的加密协议套件,该加密协议的套装名字肯定出现在客户端发送给服务器的支持的 26 个列表中,不信你可以翻回去对比一下。

(2)Certificate
HTTPS通信详解
SSL 服务器证书信息。在这条 HTTPS 服务器给客户端回复消息 SSL 握手信息里面,其还会把服务器端的 SSL 证书(server.crt)发送给客户端,从上图的转包信息中,我们能清晰地发现服务器端 SSL 证书的相关信息,比如,通用名字为 iis-web-01,组织单元为 it 等。

需要注意的是,如果是 SSL 的双向认证(比如使用u盾登录网银),服务器端也可以要求客户端把 SSL 证书发送给服务器端(对应的 SSL 握手消息名称为:CertificateRequest),这个时候,客户端就会把其 SSL 证书发送给服务器端,从而证明其就是服务器端信任的客户端。

(3)Server Key Exchange 握手消息
HTTPS通信详解
HTTPS 服务器出大招了,告诉了客户端其将会采用的 EC Diffie-Hellman 算法进行 HTTPS 服务器和客户端的秘钥交换。具体什么是 EC Diffie-Hellman 算法,大家可以自行查阅资料,这里不再赘述,并提供了 EC Diffie-Hellman 算法使用到的服务器端的参数:

  • 曲线类型:named_curve: secp256r1
  • 公钥信息
  • 签名的算法:rsa_pkcs1_sha1
  • 签名的信息

(4)Server Hello Done 握手信息。握手信息列表结束了。
HTTPS通信详解

3. HTTPS 客户端马上给服务器端回复 3 条 SSL 握手信息

当客户端收到服务器端的相关公钥信息,SSL 证书(server.crt)以及摘要算法和摘要信息后,响应了下面的 3 条 SSL 握手信息:

  • Client Key Exchange
  • Change Cipher Spec
  • Encrypted Handshake Message

那么这三条 SSL 的握手信息将会透露出什么?客户端到底想告诉服务器端什么?让我们一一分解。
(1)Client Key Exchange 握手信息
HTTPS通信详解
其给服务器端发送了一条用服务器端公钥加密的信息,其里面就包含了预备主密码(Pre-Master secret),其是由客户端随机生成,之后会被用作生成主密码的种子。根据预备密码,服务器和客户端会计算出相同的主密码(Master secret),然后根据主密码生成下面的比特序列(秘钥素材)。

  • 对称密码的秘钥
  • 消息认证码的秘钥
  • 对称密码的 CBC 模式中使用的初始化向量(IV)

需要注意的是,Client 秘钥交换的方式主要有两种,一种是通过 RSA 公钥密码进行交互,这个时候客户端会在发送 ClientKeyExchange 消息时,将经过加密的预备主密码一起发送给服务器。当使用 Diffie-Hellman 交换秘钥的时候,客户端会在发送 ClientKeyExchange 消息时,将 Diffie-Hellman 公开值(Pub Key)一起发送给服务器,根据这个值,客户端和服务器会各自生成预备主密码,而且更加这个预备主密码能够生成相同的对称主密码。

(2)Change Cipher Spec 握手信息
HTTPS通信详解
告诉服务器端,我要切换密码了!

(3)Encrypted Handshake Message 握手信息
HTTPS通信详解
客户端发出使用主密码加密的结束信息,告诉服务器端:“秘钥交换握手协议到此结束”。

4. HTTPS 服务端马上给客户端回复 2 条 SSL 握手信息
HTTPS通信详解
这次轮到服务器端发送“Change Cipher Spec”消息了,服务器告诉客户端:“好,现在我也要切换密码了”。

服务器端用预备主密码(Pre-Master secret)计算出的主秘钥加密了一条信息,并发送给客户端:“好的,秘钥交换握手协议到此结束”。如果通信双方都能把结束消息解密成功,说明主秘钥已经交换成功。就可以发送真正的用主密码加密的应用数据的信息了!

5. 服务端用对称秘钥把加密过的 HTML 网页内容发送给客户端
HTTPS通信详解
服务器端用成功交换了秘钥把加密过的 HTML 网页内容发送给客户端,客户端用以前收到过的对称秘钥进行解密,HTTPS 通信协议圆满结束。

上面的步骤只是把抓取到的使用 TL S1.2 协议规范进行了 HTTPS 通信原理和过程的梳理和解释,在不同的环境下,其通信过程会有一些差异,比如,如果配置了双向 SSL 认证,其 SSL 服务器端还会要求客户端把客户端的证书发送到服务端,从而验证客户端是否是可信任的,另外在进行主密码交换的过程中,也可能采用 RSA 公钥密码,而不是 Diffie-Hellman,此时,其 SSL 握手消息会有所不同,但是整体的流程和交互过程思路基本上保持相同。

上述具体流程如下图所示:
HTTPS通信详解

参考

http://www.ruanyifeng.com/blog/2014/02/ssl_tls.html
https://www.cnblogs.com/clsn/p/8315833.html
https://mp.weixin.qq.com/s/RSsEWxns066na8e-LjsZtA
https://www.cnblogs.com/Goden/p/4639672.html
https://www.tuicool.com/articles/aymYbmM


更多精彩内容,请订阅本人微信公众号:K8SPractice
HTTPS通信详解


如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

支付宝:                                                      微信:
HTTPS通信详解                       HTTPS通信详解