首页 > 其他分享 >11-应用层-HTTPs

11-应用层-HTTPs

时间:2023-03-11 11:34:35浏览次数:47  
标签:11 TLS 公钥 加密 HTTPS 证书 HTTPs 应用层 客户端

1. Quick Start

HTTPS(HyperText Transfer Protocol over Secure Socket Layer)超文本传输安全协议

1.1 与 HTTP 的区别?

  • HTTP 是超文本传输协议,信息是明文传输,存在安全风险的问题。HTTPS 则解决 HTTP 不安全的缺陷,在 TCP 和 HTTP 网络层之间加入了 SSL/TLS 安全协议(Transport Layer Security Protocol,传输层安全协议),使得报文能够加密传输;
  • HTTP 连接建立相对简单, TCP 三次握手之后便可进行 HTTP 的报文传输。而 HTTPS 在 TCP 三次握手之后,还需进行 SSL/TLS 的握手过程,才可进入加密报文传输;
  • 两者的默认端口不⼀样,HTTP 默认端口号是 80,HTTPS 默认端口号是 443;
  • HTTPS 协议需要向 CA(证书权威机构)申请数字证书,来保证服务器的身份是可信的。

HTTPS 解决了 HTTP 的哪些问题?

HTTP 由于是明文传输,所以安全上存在 3 个风险:窃听风险、篡改风险、冒充风险。HTTPS 在 HTTP 与 TCP 层之间加入了 SSL/TLS 协议,可以很好的解决了上述的风险:信息加密、校验机制、身份证书

HTTPS 是如何解决上面的三个风险的?

  • 混合加密的方式实现信息的机密性,解决了窃听的风险;
  • 摘要算法的方式来实现完整性,它能够为数据生成独一无二的「摘要」,摘要用于校验数据的完整性,解决了篡改的风险;
  • 将服务器公钥放入到数字证书中,解决了冒充的风险。

a. 混合加密

通过混合加密的方式可以保证信息的机密性,解决了窃听的风险。

HTTPS 采用的是对称加密非对称加密结合的「混合加密」方式:

  • 在通信建立前采用非对称加密的方式交换「会话秘钥」,后续就不再使用非对称加密。
  • 在通信过程中全部使用对称加密的「会话秘钥」的方式加密明文数据。

采用「混合加密」的方式的原因:

  • 对称加密只使用 1 个密钥,运算速度快,密钥必须保密,无法做到安全的密钥交换。
  • 非对称加密使用 2 个密钥:公钥和私钥,公钥可以任意分发而私钥保密,解决了密钥交换问题但速度慢。

b. 摘要算法+数字签名

为了保证传输的内容不被篡改,我们需要对内容计算出一个「摘要」,然后同内容一起传输给对方。

对方收到后,先是对内容也计算出一个「摘要」,然后跟发送方发送的「摘要」做一个比较,如果「摘要」相同,说明内容没有被篡改,否则就可以判断出内容被篡改了。

那么,在计算机里会用摘要算法(哈希函数)来计算出内容的哈希值,也就是内容的「摘要」,这个哈希值是唯一的,且无法通过哈希值推导出内容

通过哈希算法可以确保内容不会被篡改,但是并不能保证「内容 + 哈希值」不会被中间人替换,因为这里缺少对客户端收到的消息是否来源于服务端的证明

消息摘要算法分为三类:

  • MD(Message Digest, 消息摘要算法)
  • SHA(Secure Hash Algorithm,安全散列算法)
  • MAC(Message Authentication Code,消息认证码)

那为了避免这种情况,计算机里会用非对称加密算法来解决,共有两个密钥:

  • 一个是公钥,这个是可以公开给所有人的;
  • 一个是私钥,这个必须由本人管理,不可泄露。

这两个密钥可以双向加解密的,比如可以用公钥加密内容,然后用私钥解密,也可以用私钥加密内容,公钥解密内容。流程的不同,意味着目的也不相同:

  • 公钥加密,私钥解密。这个目的是为了保证内容传输的安全,因为被公钥加密的内容,其他人是无法解密的,只有持有私钥的人,才能解密出实际的内容;
  • 私钥加密,公钥解密。这个目的是为了保证消息不会被冒充,因为私钥是不可泄露的,如果公钥能正常解密出私钥加密的内容,就能证明这个消息是来源于持有私钥身份的人发送的。

一般我们不会用非对称加密来加密实际的传输内容,因为非对称加密的计算比较耗费性能的。

所以非对称加密的用途主要在于通过「私钥加密,公钥解密」的方式,来确认消息的身份,我们常说的数字签名算法,就是用的是这种方式,不过私钥加密内容不是内容本身,而是对内容的哈希值加密

私钥是由服务端保管,然后服务端会向客户端颁发对应的公钥。如果客户端收到的信息,能被公钥解密,就说明该消息是由服务器发送的。

【小结】TLS 的功能实现主要依赖于 3 类基本算法:散列函数 Hash、对称加密、非对称加密。其利用非对称加密实现身份认证和密钥协商,对称加密算法采用协商的密钥对数据加密通讯,基于散列函数验证信息的完整性。

c. 数字证书

前面我们知道:

  • 可以通过哈希算法来保证消息的完整性;
  • 可以通过数字签名来保证消息的来源可靠性(能确认消息是由持有私钥的一方发送的);

但是这还远远不够,还缺少身份验证的环节,万一公钥是被伪造的呢?


举个例子,你想向老师请假,一般来说是要求由家长写一份请假理由并签名,老师才能允许你请假。虽然你妈妈持有私钥,老师通过是否能用公钥解密来确认这个请假条是不是来源你母亲的。但是我们还可以自己伪造出一对公私钥啊!

你找了个夜晚,偷偷把老师桌面上和你妈妈配对的公钥,换成了你的公钥,那么下次你在请假的时候,你继续模仿你妈妈的字迹写了个请假条,然后用你的私钥做个了「数字签名」。

但是老师并不知道自己的公钥被你替换过了,所以她还是按照往常一样用公钥解密,由于这个公钥和你的私钥是配对的,老师当然能用这个被替换的公钥解密出来,并且确认了内容的完整性,于是老师就会以为是你母亲写的请假条,又允许你请假了。

正所谓魔高一丈,道高一尺。

既然伪造公私钥那么随意,所以你妈把她的公钥注册到警察局,警察局用她们自己的私钥对你母亲的公钥做了个数字签名,然后把你妈妈的「个人信息 + 公钥 + 数字签名」打包成一个数字证书,也就是说这个数字证书包含你妈妈的公钥。

这样,你妈妈如果因为家里确实有事要向老师帮你请假的时候,不仅会用自己的私钥对内容进行签名,还会把数字证书给到老师。

老师拿到了数字证书后,首先会去警察局验证这个数字证书是否合法,因为数字证书里有警察局的数字签名,警察局要验证证书合法性的时候,用自己的公钥解密,如果能解密成功,就说明这个数字证书是在警察局注册过的,就认为该数字证书是合法的,然后就会把数字证书里头的公钥(你妈妈的)给到老师。

由于通过警察局验证了数字证书是合法的,那么就能证明这个公钥就是你母亲的,于是老师就可以安心的用这个公钥解密出请假条,如果能解密出,就证明是你妈妈写的请假条。

正是通过了一个权威的机构来证明你妈妈的身份,所以你的伪造公私钥这个小伎俩就没用了。


在计算机里,这个权威的机构就是 CA (数字证书认证机构),将服务器公钥放在数字证书(由数字证书认证机构颁发)中,只要证书是可信的,公钥就是可信的。

通过数字证书的方式保证服务器公钥的身份,解决冒充的风险。

1.2 如何建立连接的?

SSL/TLS 协议基本流程:

  1. 客户端向服务器索要并验证服务器的公钥。
  2. 双方协商生产「会话秘钥」。
  3. 双方采用「会话秘钥」进行加密通信。

前两步也就是 SSL/TLS 的建立过程,也就是 TLS 握手阶段。

TLS 的「握手阶段」涉及四次通信,使用不同的密钥交换算法,TLS 握手流程也会不一样的,现在常用的密钥交换算法有两种:RSA 算法和 ECDHE 算法。

基于 RSA 算法的 TLS 握手过程比较容易理解(明文 → 非对称加密 → 对称加密),所以这里先用这个给大家展示 TLS 握手过程,如下图:

a. ClientHello

首先,由客户端向服务器发起加密通信请求,也就是 ClientHello 请求。

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

  • 客户端支持的 TLS 协议版本,如 TLS 1.2 版本;
  • 客户端生产的随机数(Client Random),后面用于生成「会话秘钥」条件之一;
  • 客户端支持的密码套件列表,如 RSA 加密算法;

b. SeverHello

服务器收到客户端请求后,向客户端发出响应,也就是 SeverHello。服务器回应的内容有如下内容:

  • 确认 TLS 协议版本,如果浏览器不支持,则关闭加密通信;
  • 服务器生产的随机数(Server Random),也是后面用于生产「会话秘钥」条件之一;
  • 确认的密码套件列表,如 RSA 加密算法;
  • 服务器的数字证书;

c. ClientResp

客户端收到服务器的回应之后,首先通过浏览器或者操作系统中的 CA 公钥,确认服务器的数字证书的真实性。

如果证书没有问题,客户端会从数字证书中取出服务器的公钥,然后使用它加密报文,向服务器发送如下信息:

  • 一个随机数(pre-master key)。该随机数会被服务器公钥加密;
  • 加密通信算法改变通知,表示随后的信息都将用「会话秘钥」加密通信;
  • 客户端握手结束通知,表示客户端的握手阶段已经结束。这一项同时把之前所有内容的发生的数据做个摘要,用来供服务端校验;

上面第一项的随机数是整个握手阶段的第 3 个随机数,会发给服务端,所以这个随机数客户端和服务端都是一样的。

服务器和客户端有了这三个随机数(Client Random、Server Random、pre-master key),接着就用双方协商的加密算法,各自生成本次通信的「会话秘钥」

d. ServerResp

服务器收到客户端的第 3 个随机数(pre-master key)之后,通过协商的加密算法,计算出本次通信的「会话秘钥」。

然后,向客户端发送最后的信息:

  • 加密通信算法改变通知,表示随后的信息都将用「会话秘钥」加密通信;
  • 服务器握手结束通知,表示服务器的握手阶段已经结束。这一项同时把之前所有内容的发生的数据做个摘要,用来供客户端校验;

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

1.3 如何校验数字证书?

接下来,详细说一下实际中数字证书签发验证流程:

CA 签发证书的过程,如上图左边部分:

  • 首先 CA 会把持有者的公钥、用途、颁发者、有效时间等信息打成一个包,然后对这些信息进行 Hash 计算,得到一个 Hash 值;
  • 然后 CA 会使用自己的私钥将该 Hash 值加密,生成 Certificate Signature,也就是 CA 对证书做了签名;
  • 最后将 Certificate Signature 添加在文件证书上,形成数字证书;

客户端校验服务端的数字证书的过程,如上图右边部分:

  • 首先客户端会使用同样的 Hash 算法获取该证书的 Hash 值 H1;
  • 通常浏览器和操作系统中集成了 CA 的公钥信息,浏览器收到证书后可以使用 CA 的公钥解密 Certificate Signature 内容,得到一个 Hash 值 H2 ;
  • 最后比较 H1 和 H2,如果值相同,则为可信赖的证书,否则则认为证书不可信。

但事实上,证书的验证过程中还存在一个证书信任链的问题,因为我们向 CA 申请的证书一般不是根证书签发的,而是由中间证书签发的,比如百度的证书,从下图你可以看到,证书的层级有三级:

对于这种三级层级关系的证书的验证过程如下:

  1. 客户端收到 baidu.com 的证书后,发现这个证书的签发者不是根证书,就无法根据本地已有的根证书中的公钥去验证 baidu.com 证书是否可信。于是,客户端根据 baidu.com 证书中的签发者,找到该证书的颁发机构是 “GlobalSign Organization Validation CA - SHA256 - G2”,然后向 CA 请求该中间证书。
  2. 请求到证书后发现 “GlobalSign Organization Validation CA - SHA256 - G2” 证书是由 “GlobalSign Root CA” 签发的,由于 “GlobalSign Root CA” 没有再上级签发机构,说明它是根证书,也就是自签证书。应用软件会检查此证书有否已预载于根证书清单上,如果有,则可以利用根证书中的公钥去验证 “GlobalSign Organization Validation CA - SHA256 - G2” 证书,如果发现验证通过,就认为该中间证书是可信的。
  3. “GlobalSign Organization Validation CA - SHA256 - G2” 证书被信任后,可以使用 “GlobalSign Organization Validation CA - SHA256 - G2” 证书中的公钥去验证 baidu.com 证书的可信性,如果验证通过,就可以信任 baidu.com 证书。

在这 3 个步骤中,最开始客户端只信任根证书 GlobalSign Root CA 证书的,然后 “GlobalSign Root CA” 证书信任 “GlobalSign Organization Validation CA - SHA256 - G2” 证书,而 “GlobalSign Organization Validation CA - SHA256 - G2” 证书又信任 baidu.com 证书,于是客户端也信任 baidu.com 证书。

总括来说,由于用户信任 GlobalSign,所以由 GlobalSign 所担保的 baidu.com 可以被信任,另外由于用户信任操作系统或浏览器的软件商,所以由软件商预载了根证书的 GlobalSign 都可被信任。

操作系统里一般都会内置一些根证书,比如我的电脑里内置的根证书有这么多:

这样的一层层地验证就构成了一条信任链路,整个证书信任链验证流程如下图所示:

最后一个问题,为什么需要证书链这么麻烦的流程?Root CA 为什么不直接颁发证书,而是要搞那么多中间层级呢?

这是为了确保根证书的绝对安全性,将根证书隔离地越严格越好,不然根证书如果失守了,那么整个信任链都会有问题。

1.4 如何保证数据完整性?

TLS 在实现上分为握手层记录层两层。

  • TLS 记录协议(TLS Record protocol)
    • TLS 记录协议位于 TLS 握手协议的下层,是负责使用对称密码对消息进行加密通信的部分;
    • 加密使用的密钥是通过 TLS 握手协议(TLS Handshaking Protocols)在服务器和客户端之间协商决定的;
    • 负责保护应用程序数据并验证其完整性和来源,所以对 HTTP 数据加密是使用记录协议;
  • TLS 握手层·协议
    • TLS 握手协议(TLS Handshaking Protocols)就是我们前面说的 TLS 四次握手的过程,负责协商加密算法和生成对称密钥,后续用此密钥来保护应用程序数据(即 HTTP 数据);
    • 密码规格变更协议(TLS Change Spec Protocol)负责向通信对象传达变更密码方式的信号;
    • 警告协议(TLS Alert Protocol)是 TLS 握手协议负责在发送错误时将错误传达给对方;

TLS 记录协议主要负责消息(HTTP 数据)的压缩,加密及数据的认证,过程如下图:

具体过程如下:

  • 首先,消息被分割成多个较短的片段,然后分别对每个片段进行压缩;
  • 接下来,经过压缩的片段会被加上消息认证码(MAC 值,这个是通过哈希算法生成的),这是为了保证完整性,并进行数据的认证。通过附加消息认证码的 MAC 值,可以识别出篡改。与此同时,为了防止重放攻击,在计算消息认证码时,还加上了片段的编码;
  • 再接下来,经过压缩的片段再加上消息认证码会一起通过对称密码进行加密;
  • 最后,上述经过加密的数据再加上由数据类型、版本号、压缩后的长度组成的报头就是最终的报文数据。

记录协议完成后,最终的报文数据将传递到传输控制协议层(TCP)进行传输。

1.5 HTTPs 一定安全可靠吗?

【问题场景】客户端通过浏览器向服务端发起 HTTPS 请求时,被「假基站」转发到了一个「中间人服务器」,于是客户端是和「中间人服务器」完成了 TLS 握手,然后这个「中间人服务器」再与真正的服务端完成 TLS 握手。

具体过程如下:

  • 「客户端」向「服务端」发起 HTTPS 建立连接请求时,然后被「假基站」转发到了一个「中间人服务器」,接着「中间人」向「服务端」发起 HTTPS 建立连接请求,此时「客户端」与「中间人」进行 TLS 握手,「中间人」与「服务端」进行 TLS 握手;
  • 在「客户端」与「中间人」进行 TLS 握手过程中,中间人会发送自己的公钥证书给客户端,「客户端」验证证书的真伪,然后从证书拿到公钥,并生成一个随机数,用公钥加密随机数发送给「中间人」,「中间人」使用私钥解密,得到随机数,此时双方都有随机数,然后通过算法生成对称加密密钥(A),后续「客户端」与「中间人」通信就用这个对称加密密钥来加密数据了。
  • 在「中间人」与「服务端」进行 TLS 握手过程中,「服务端」会发送从 CA 机构签发的公钥证书给「中间人」,从证书拿到公钥,并生成一个随机数,用公钥加密随机数发送给「服务端」,「服务端」使用私钥解密,得到随机数,此时双方都有随机数,然后通过算法生成对称加密密钥(B),后续「中间人」与「服务端」通信就用这个对称加密密钥来加密数据了。
  • 后续的通信过程中,「中间人」用对称加密密钥(A)解密「客户端」的 HTTPS 请求的数据,然后用对称加密密钥(B)加密 HTTPS 请求后,转发给「服务端」,接着「服务端」发送 HTTPS 响应数据给「中间人」,「中间人」用对称加密密钥(B)解密 HTTPS 响应数据,然后再用对称加密密钥(A)加密后,转发给「客户端」。

从客户端的角度看,其实并不知道网络中存在中间人服务器这个角色。那么中间人就可以解开浏览器发起的 HTTPS 请求里的数据,也可以解开服务端响应给浏览器的 HTTPS 响应数据。相当于,中间人能够 “偷看” 浏览器与服务端之间的 HTTPS 请求和响应的数据。

但是要发生这种场景是有前提的,前提是用户点击接受了中间人服务器的证书。

中间人服务器与客户端在 TLS 握手过程中,实际上发送了自己伪造的证书给浏览器,而这个伪造的证书是能被浏览器(客户端)识别出是非法的,于是就会提醒用户该证书存在问题。

如果用户执意点击「继续浏览此网站」,相当于用户接受了中间人伪造的证书,那么后续整个 HTTPS 通信都能被中间人监听了。所以,这其实并不能说 HTTPS 不够安全,毕竟浏览器都已经提示证书有问题了,如果用户坚决要访问,那不能怪 HTTPS ,得怪自己手贱。

另外,如果你的电脑中毒了,被恶意导入了中间人的根证书,那么在验证中间人的证书的时候,由于你操作系统信任了中间人的根证书,那么等同于中间人的证书是合法的,这种情况下,浏览器是不会弹出证书存在问题的风险提醒的。这其实也不关 HTTPS 的事情,是你电脑中毒了才导致 HTTPS 数据被中间人劫持的。

所以,HTTPS 协议本身到目前为止还是没有任何漏洞的,即使你成功进行中间人攻击,本质上是利用了客户端的漏洞(用户点击继续访问或者被恶意导入伪造的根证书),并不是 HTTPS 不够安全

为什么抓包工具能截取 HTTPS 数据?

很多抓包工具 之所以可以明文看到 HTTPS 数据,工作原理与中间人一致的。

对于 HTTPS 连接来说,中间人要满足以下两点,才能实现真正的明文代理:

  1. 中间人,作为客户端与真实服务端建立连接这一步不会有问题,因为服务端不会校验客户端的身份;
  2. 中间人,作为服务端与真实客户端建立连接,这里会有客户端信任服务端的问题,也就是服务端必须有对应域名的私钥;

中间人要拿到私钥只能通过如下方式:

  1. 去网站服务端拿到私钥;
  2. 去 CA 拿域名签发私钥;
  3. 自己签发证书,且要被浏览器信任;

不用解释,抓包工具只能使用第三种方式取得中间人的身份。

使用抓包工具进行 HTTPS 抓包的时候,需要在客户端安装 Fiddler 的根证书,这里实际上起认证中心(CA)的作用。

抓包工具能够抓包的关键是客户端会往系统受信任的根证书列表中导入抓包工具生成的证书,而这个证书会被浏览器信任,也就是抓包工具给自己创建了一个认证中心 CA,客户端拿着中间人签发的证书去中间人自己的 CA 去认证,当然认为这个证书是有效的。

如何避免被中间人抓取数据?

我们要保证自己电脑的安全,不要被病毒乘虚而入,而且也不要点击任何证书非法的网站,这样 HTTPS 数据就不会被中间人截取到了。

当然,我们还可以通过 HTTPS 双向认证来避免这种问题。

一般我们的 HTTPS 是单向认证,客户端只会验证了服务端的身份,但是服务端并不会验证客户端的身份。

如果用了双向认证方式,不仅客户端会验证服务端的身份,而且服务端也会验证客户端的身份。服务端一旦验证到请求自己的客户端为不可信任的,服务端就拒绝继续通信,客户端如果发现服务端为不可信任的,那么也中止通信。

2. HTTPS RSA 握手解析

3. HTTPS ECDHE 握手解析

标签:11,TLS,公钥,加密,HTTPS,证书,HTTPs,应用层,客户端
From: https://www.cnblogs.com/liujiaqi1101/p/17205545.html

相关文章

  • 2023.03.11.函数重载,引用等
    程序生成的过程:1.预处理:头文件的展开宏的替换预处理指令解析去掉注释2.编译:预处理后文件生成汇编文件.asm(汇编代码)词法解析,语法解析语义分析优化3.汇编:汇编文件进一......
  • 2023.03.11.命名空间
    c++命名空间为了区分不同库中相同名称的函数、类、变量等命名空间的定义使用关键字namespace,后跟命名空间的名称,如下所示:namespacenamespace_name{//代码声明}为......
  • 程序设计应用 2023-03-11
     DjangodoessupporttheModel-View-Controller(MVC)architecturalpattern.However,DjangousesaslightlydifferentapproachcalledModel-View-Template(MV......
  • 多媒体技术 2023-03-11
    音频的获取与处理2.1声音的基础知识声音的三个要素是音调、音强和音色。音调是指声音的高低,由频率决定。高频率的声音听起来高,低频率的声音听起来低。音乐中按音阶来表......
  • Linux Kernel 4.8.11版本发布
    在感恩节的周末,Linux Kernel4.8稳定版分支和4.4LTS分支都获得了维护版本更新。今天发布的LinuxKernel4.8.11和此前的4.8.10版本相隔5天时间,根据短日志主要对77......
  • Linux Kernel 4.8.11版本发布
    在感恩节的周末,​​Linux​​ Kernel4.8稳定版分支和4.4LTS分支都获得了维护版本更新。今天发布的LinuxKernel4.8.11和此前的4.8.10版本相隔5天时间,根据短日志主要对77......
  • ES6-ES11 ES10-Symbol.prototype.description
    原视频<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><title......
  • ES6-ES11 ES10字符串方法扩展-trimStart-trimEnd
    原视频<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><title......
  • ES6-ES11 ES10数组方法扩展-flat与flatMap
    原视频<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><title......
  • 修复win11重置网络后有线无线均无法连接网络/没有WiFi图标问题
    win11网络重置,点击立即重置,然后出现了WiFi图标不见了,只剩下蓝牙、飞行模式、节电模式等五个模块。并且在设备管理器-网络适配器中驱动前都是黄色感叹号,双击查看状态为:代码5......