• 【Linux】HTTPS协议


    📖 前言

    在上一章中,我们学习了http协议,了解了其层状的结构,并对其常见报头,方法,各种特性有了相关的认识。本章我们紧接着学习https这一协议。分析通信时是如何加密的,主要的策略有哪些,并了解现在主流的加密措施等。目标已经,搬好小板凳,准备开讲啦… 👉 http协议复习


    1. 引入https协议

    在上一章节中,我们学习了http协议,我们知道http协议是具有安全隐患的,最主要的原因就是其是明文传输的!

    HTTP的安全隐患主要包括以下几点:

    1. 数据明文传输:HTTP传输的数据是明文的,容易被截取和窃听。
    2. 缺乏身份验证:HTTP协议不提供对用户身份的验证机制,易受到伪造请求的攻击。
    3. 客户端篡改风险:攻击者可以在传输过程中修改数据包内容,实施各种攻击。
    4. 中间人攻击:攻击者可以截取数据并可能修改数据内容,通信双方都不知情。

    为了解决这些问题,发展出了HTTPS(HTTP Secure)协议:

    • 它在HTTP的基础上引入了SSL/TLS协议,通过对数据进行加密和身份验证,使得通信更加安全可靠。
    • 在使用HTTP时,尽量避免传输敏感信息,并在必要时考虑使用其他安全手段,如对数据进行加密,加强身份验证等。

    现在主流的已经不是http了,都是https了~

    http直接使用传输层的接口套接字,http是用传输层的接口来使用网络层的协议来进行通信。构建http的response和request二进制流。数据和正文都是明文的,有人拿到了数据就能看到,不安全!!

    在这里插入图片描述
    可以选加密或者不加密,加密就是https,不加密就是http。SSL/TLS在http协议下侧,属于软件层。

    同层的http协议并不关心如何加密,同层的http也不需要关心如何解密:

    • 拿到的数据就是发送之前是明文,收到之后也是明文,并不影响上层http的使用。
      • 中间经历了加密解密的过程。
    • 通过加软件层的方式解决数据安全的问题。

    所有的加密,都是为了防止中间有人进行窃取和篡改!

    具体解释:

    • 应用层已经写好的协议最典型的就是http协议。
    • http协议最开始的时候的逻辑直接调用的是传输层对应的接口,没有安全策略,在功能上保证完成通信就好。
    • 但是不太安全,于是在http和传输层之间加了一层软件层,SSL/TLS加密层(也是属于应用层的),浏览器和服务端都支持。
    • 发送的http请求,并不是直接交给传输层,而是先交给加密层进行加密,完成之后形成的二进制数据再交给传输层。
    • 传输层会封装自己的报头,根本就不关心自己的有效载荷是什么,有效载荷的格式也不关心。
    • 传输层将加密之后的http请求经过网络发送给对方。
    • 对方在向上交付时,因为http采用的端口是80,https采用的端口是443。
    • 所以传输层在收到了一个请求之后,会根据绑定的端口来判断交付给那个进程。
    • 如果请求报文请求的是443,就将请求交给443,实际上是交给了服务端的SSL/ TLS加密解密层,对数据进行解密。

    这就保证了数据在中间传输过程中,一旦被截取了,也不会对数据进行篡改。

    http + SSL/TLS合起来称之为https。


    2. 常见的加密方式

    加密就能解决彻底解决安全问题吗?不能!单纯依靠加密是解决不了问题的!还需要一套综合的方案!

    • 什么是加密:

    加密就是把明⽂(要传输的信息)进行一系列变换,⽣成密⽂。

    • 什么是解密:

    解密就是把密⽂再进⾏⼀系列变换,还原成明⽂。

    • 什么是密钥:

    在这个加密和解密的过程中,往往需要⼀个或者多个中间的数据,辅助进⾏这个过程这样的数据称为密钥

    • 密钥就是对应的一段数据,根据不同的加密算法,密钥肯定不一样。
    • 但是一般是可以通过特定的加密算法,采用特定的密钥来对明文做加密。
    • 加密之后就可以形成对应的密文。

    2.1 对称加密:

    概念简述:

    • 采⽤单钥密码系统的加密⽅法,同⼀个密钥可以同时⽤作信息的加密和解密。
    • 这种加密⽅法称为对称加密,也称为单密钥加密。

    特征:加密和解密所用的密钥是相同的。

    周边概念:

    • 常见对称加密算法:DES、3DES、AES、TDEA、Blowfish、RC2…
    • 特点:算法公开,计算量小,加密速度快,加密效率⾼。

    举个栗子:

    • 假设明文x,密钥key
    • 则加密x ^ key得到的密文y
    • 然后针对密文y再次进行运算y ^ key,得到的就是原来的明文x

    2.2 非对称加密:

    概念简述:

    • 需要两个密钥来进行加密和解密。
    • 这两个密钥是公开密钥(public key,简称公钥)。
    • 和私有密钥(private key,简称私钥)。

    特点:算法强度复杂,安全性依赖于算法与密钥,但是由于其算法复杂,而使得加密解密速度没有对称加密解密的速度快。

    周边概念:

    • 公钥和私钥是配对的,最大的缺点就是运算速度非常慢,比对称加密要慢很多。
    • 可以正着用:
      • 通过公钥对明文加密,变成密文。
      • 通过私钥对密文解密,变成明文。
    • 也可以反着用:
      • 通过私钥对明文加密,变成密文。
      • 通过公钥对密文解密,变成明文。

    非对称加密,有两个秘钥,一个密钥叫公钥, 一个密钥叫私钥。两个密钥,任何一个都能叫做公钥或私钥,选择其中某一个公开这就叫做公钥,自己保留好不让别人看到的叫做私钥。用私钥加密,公钥解密这种算法叫非对称。

    举个栗子:

    • 甲要给乙一些重要的文件,但是乙可能不在于是甲和乙提前做出约定。
    • 乙说:我桌子上有个盒子,然后我给你一把锁,你把文件放盒子里用锁锁上,然后我回头拿着钥匙来开锁取文件。
    • 在这个场景中,这把锁就相当于公钥,钥匙就是私钥,公钥给谁都行(不怕泄露),但是私钥只有乙自己持有,持有私钥的人才能解密。

    2.3 数据摘要&&数据指纹:

    数字指纹(数据摘要),其基本原理是利用单向散列函数(Hash函数)对信息进行运算,生成一串固定长度的数字摘要。数字指纹并不是一种加密机制,但可以用来判断数据有没有被篡改。

    数据摘要只有数据加密,没有数据解密(哈希算法是不可能的),严格意义来讲不算是加密算法(因为不能解密),但是可以判断信息是否被篡改,摘要是不可能反推回原信息的。

    因为没有解密,只不过从摘要很难反推原信息,通常用来进行数据对比。

    数字签名:摘要经过加密,就得到数字签名。


    3. 对加密方式的探究

    加密的方式有很多,但是整体可以分成两大类:对称加密和非对称加密

    3.1 只使用对称加密:

    如果通信双方都各自持有同一个密钥X,且没有别人知道,这两方的通信安全当然是可以被保证的(除
    非密钥被破解)。

    引入对称加密之后,即使数据被截获,由于黑客不知道密钥是啥,因此就无法进行解密,也就不知道请求的真实内容是啥了。

    但是真的就这么简单的解决了吗?答案是否定的!

    • 但事情没这么简单,服务器同一时刻其实是给很多客户端提供服务的。
    • 这么多客户端,每个人用的密钥都必须是不同的!
      • 如果是相同那密钥就太容易扩散了,黑客就也能拿到了。
    • 因此服务器就需要维护每个客户端和每个密钥之间的关联关系,这也是个很麻烦的事情。

    比较理想的做法,就是能在客户端和服务器建立连接的时候,双方协商确定这次的密钥是啥~

    客户端如何拿到密钥?

    • 首先想到的是将密钥内置在客户端的浏览器内:
      • 显然这是不可取的,这样都不能叫密钥了,大家都能拿到这个密钥,都可以对密文解密,加密形同虚设。
    • 其次想到的是,客户端将密钥发送给客户端:
      • 那么一旦中间人(黑客)拿到了密钥,就可以对密文解密,那么之前的加密形同虚设。
    • 那可以将密钥加密然后发送给客户端吗?
      • 可以,但是客户端如何拿到被加密之后的密钥所形成的密文的密钥呢?
      • 显然服务端还需要将被加密之后的密钥所形成的密文的密钥发送给客户端,那么该密钥要是被中间人截取了呢?
      • 显然这是一个无穷无尽的问题,一直套下去,解决不了问题。

    3.2 只使用非对称加密:

    公钥加密的密文,只能用私钥解密,私钥加密的密文,只能用公钥解密!!

    非对称加密过程图:

    在这里插入图片描述

    • 如果服务器先把公钥以明文方式传输给浏览器。
    • 之后浏览器向服务器传数据前都先用这个公钥加密好再传。
    • 从客户端到服务器信道似乎是安全的(但是也有安全问题)。
    • 因为只有服务器有相应的私钥能解开公钥加密的数据。

    但是服务器到浏览器的这条信道怎么保障安全?(重点)

    • 非对称加密,服务器想向客户端发消息,服务器不能用公钥加密。
    • 因为客户端没有私钥,客户端没办法解密。
    • 所以只能用私钥加密并将公钥发送给客户端,客户端再用公钥解密。
    • 但是中间人也会持有公钥,私钥加密的密文也会形同虚设。

    所以,反向的从服务器单发送给客户端,这条信道是不安全的,而且暂时还没有解决方案。

    3.3 双方都使用非对称加密:

    加密解密过程:

    1. 服务端拥有公钥S与对应的私钥S',客户端拥有公钥C与对应的私钥C'
    2. 客户和服务端交换公钥。
    3. 客户端给服务端发信息:先用S对数据加密再发送,只能由服务器解密,因为只有服务器有私钥S'
    4. 服务端给客户端发信息:先用C对数据加密再发送,只能由客户端解密,因为只有客户端有私钥C'

    这种是看似是安全的(依旧有安全问题),但是效率过于低下,是用户接受不了的。

    3.4 非对称加密 + 对称加密:

    首当其冲的我们要解决效率的问题!

    1. 客户端发起https请求,获取服务端公钥S
    2. 客户端在本地生成对称密钥C,通过公钥S加密后发送给服务器。
    3. 由于中间人没有私钥S',即使截获了数据,也无法还原出对称密钥C(其实也不一定)。
    4. 服务器通过私钥S解密,还原出客户端发送的对称密钥C,并且使用这个对称密钥C加密给客户端返回的响应数据。

    后续客户端和服务器的通信都只用对称密钥C加密即可,因为该密钥只有客户端和服务器两个主机知道,其他主机和设备即使截获数据也没有意义。

    3.5 共性问题:

    虽然上一种方案已经接近完美了,看似很安全,但是依旧存在安全问题!

    方案2,方案3,方案4,都存在一个问题,如果在最开始,中间人就已经开始攻击了呢?

    针对于 方案4 的问题:

    在这里插入图片描述
    重点:

    客户端无法确定收到的含有公钥的数据报文,就是目标服务器发送过来的!!

    针对于 方案2,方案3 的问题:

    • 中间人将公钥换成自己的公钥,并发给客户端。
    • 客户端会误以为中间人发来的公钥是服务端发来的。
    • 所以就用中间人的公钥将数据加密成密文,发给服务端。
    • 中间人依旧会截获密文,用自己的私钥解密,就能得到数据,也是不安全的!

    上述分析是截获客户端数据,同样的反过来中间人截获服务端数据也是一样的方式。这就是之前在讲前三个方案时括号内的备注不安全的原因。


    4. CA证书认证

    上述四种方案都是有问题的,那么怎么样证明,收到的公钥就是合法的主机发来的呢?

    证书是用来标识服务器是否合法的一种策略。

    4.1 CA认证:

    服务端在使用HTTPS前,需要向CA机构申领一份数字证书,数字证书里含有证书申请者信息,公钥信息等。服务器把证书传输给浏览器,浏览器从证书里获取公钥就行了,证书就如身份证,证明服务端请求一个服务器,会返回一个证书给客户端

    • 请求服务器时,服务器可不仅仅是把公钥给客户端,是给了一批数据,把所有数据都打了个包,放在了一个叫证书的东西上。
    • 方案四当中,客户端请求时,服务端返回公钥S,不叫做返回服务端公钥S,而叫做获取服务端证书,证书是一对信息的集合。

    这个证书可以理解成是一个结构化的字符串,里面包含了以下信息:

    证书发布机构、证书有效期、公钥、证书所有者、签名 …

    • 需要注意的是:申请证书的时候,需要在特定平台生成。
    • 会同时生成一对密钥对,即公钥和私钥。
    • 这对密钥对就是用来在网络通信中进行明文加密以及数字签名的。
    • 其中服务端的公钥会随着CSR文件,一起发给CA进行权威认证,私钥服务端自己保留,用来后续进行通信(其实主要就是用来交换对称秘钥)。

    4.2 理解数据签名:

    签名的形成是基于非对称加密算法的,注意,目前暂时和https没有关系,不要和https中的公钥私钥搞混了。
    在这里插入图片描述
    图中的数据可以理解为证书。

    当服务端申请CA证书的时候,CA机构会对该服务端进行审核,并专门为该网站形成数字签名,过程如下:

    1. CA机构拥有非对称加密的私钥A公钥A'
    2. CA机构对服务端申请的证书明文数据进行hash,形成数据摘要。
    3. 然后对数据摘要用CA的私钥A'加密,得到数字签名S
    4. 服务端申请的证书明文数字签名S共同组成了数字证书,这样一份数字证书就可以颁发给服务端了。

    5. 非对称加密 + 对称加密 + 证书认证

    在客户端和服务器刚一建立连接的时候,服务器给客户端返回一个证书,证书包含了【当前服务端的公钥】,也包含了网站的身份信息。

    客户端进行认证:

    • 当客户端获取到这个证书之后,会对证书进行校验(防止证书是伪造的)。
    • 判定证书的有效期是否过期。
    • 判定证书的发布机构是否受信任(操作系统中已内置的受信任的证书发布机构)。

    验证证书是否被篡改:

    • 从系统中拿到该证书发布机构的公钥,对签名解密,得到一个hash值(称为数据摘要),设为hash1
    • 然后计算出整个证书的hash值,设为hash2,对比hash1hash2是否相等。
    • 如果相等,则说明证书是没有被篡改过的。

    CA机构将【解密数字签名的公钥】也会内置在浏览器内部或者电脑内部的。

    客户端小结:

    1. 拿着证书原文做哈希得到摘要。
    2. 拿着CA机构的公钥对签名做解密,形成摘要。
    3. 两个摘要作对比就能知道证书是否被篡改过。
    • 服务器提前在自己的网站https被使用之前,要去CA机构申请证书。
    • 从此往后所有要访问这个网站的客户端要请求这个网站,都要拉取证书的。
    • 证书里有以明文传送的证书和数据签名附在证书上。
    • 因为世界上只有CA有私钥,只有CA机构能够对这个明文重新签名。
    • CA机构将公钥暴露给所有人,客户端对签名进行解密得到摘要,对证书明文重新哈希,也形成摘要,两个摘要一对比,就发现这个证书是否被篡改。

    这样就能保证客户端收到的【服务器的公钥】一定是目标服务器发过来的了!!

    证书验证通过后,客户端从证书中提取服务器的公钥。
    客户端生成一个随机的对称密钥,并使用服务器的公钥对对称密钥进行加密。
    客户端将加密后的对称密钥发送给服务器。
    服务器收到客户端发送的加密对称密钥后,使用自己的私钥进行解密,得到对称密钥。
    服务器和客户端之间使用对称密钥进行后续的通信,实现加密传输。

    还会有安全隐患吗?

    • 如果中间人把证书的明文改了:
      • 由于中间人没有CA机构的私钥,就无法对哈希之后的数据摘要做私钥加密,重新形成新的签名。
      • 那么就无法对篡改之后的证书形成匹配的签名。
      • 如果强行的篡改,客户端收到证书之后,会发现收到的明文哈希之后的摘要,和签名解密之后的摘要不一致。
      • 就证明这个证书已经经被篡改了,证书不可信,从而直接终止向服务器传送信息。
    • 中间人既然修改不了证书,如果中间人用自己的私钥将证书的明文形成的摘要加密形成签名给客户端:
      • 这也是不行的,因为客户端认证证书的时候,只会用匹配的CA机构的公钥来解密。
      • 自然解密不了中间人用私钥加密的证书明文(谁认你啊~)。
      • 所以中间人是无法对证书做任何修改的,即便证书是明文传送的。

    所以https是一套:非对称加密 + 对称加密 + 证书认证的机制。

    为什么摘要内容在网络传输的时候一定要加密形成签名?

    • 因为只要知道哈希算法(而且哈希算法一般都是公开的),只要拿到明文,知道哈希算法,自己也可以形成摘要。
    • 如果不对它做加密的话,将明文直接传过去,中间人如果将明文改掉,重新形成的摘要,认证就没有意义了。

    为什么签名不直接加密,而是要先hash形成摘要?

    • 是为了缩小签名密文的长度,加快验证时的运算速度。

    查看浏览器内置的证书:

    在这里插入图片描述
    在这里插入图片描述

    • 传统的TLS/SSL连接确实是由服务器向浏览器发送证书,然后浏览器通过验证该证书来确认服务器的身份和信任。
    • 在这个过程中,浏览器会检查证书的有效性、签名机构的可信度等信息。
    • 然而,浏览器也可以内置一些常用的根证书,这些证书是由各大公认的证书颁发机构(CA)所签署的,并被广泛接受和信任。
    • 内置证书的目的是为了方便用户,使得用户不需要手动验证每个网站的证书。
    • 当浏览器访问一个使用内置证书的网站时,浏览器会自动使用内置的根证书来验证服务器发送的证书。
    • 只有在该证书通过验证,且与已知的根证书匹配时,浏览器才会显示网站是安全可信的。

    总结起来,浏览器内置证书是为了简化用户验证过程,并提供更好的用户体验。

  • 相关阅读:
    C# 中的 Math 数学函数
    【java】网络编程
    【Tronlong TLT113 Series--1 Env Install】
    查找算法——二分查找
    IB数学与音乐的融合
    android service基本介绍
    openGauss学习笔记-95 openGauss 数据库管理-访问外部数据库-postgres_fdw
    Qt(day2)
    Java 和低延迟
    Android ADB 常见问题和注意事项
  • 原文地址:https://blog.csdn.net/m0_63059866/article/details/133770446