SSL/TLS 协议

11.TLS

SSL/TLS 协议

不知道大家平时有没有思考过所谓端到端加密是如何在别人眼皮子底下建立起只有通信双方能够解密的通信信道的,HTTPS又比HTTP多了什么才更加安全呢,又或者是TLS和DNS这种看似不相关的协议是否存在联动呢,CA认证是干什么的呢,客户端经过什么样的过程才信任服务器呢。以上都是我本人平时的胡思乱想🤔,而契机是读论文时发现可以对SNI进行加密,但这个加密发生在TLS密钥交换之前,我就很好奇这是如何实现的,尽管这个问题属于TLS协议的边缘问题,也不难回答,但重要的是它成为了我去了解TLS协议具体过程的引子,而本文是我在学习之后做的一个浅浅的总结。

背景及作用

  • SSL/TLS是一种加密协议,广泛用于在网络通信时建立端到端加密信道(HTTPS、VPN、电子邮件(SMTPS/IMAPS)等),安全地传输数据,它能够确保通信地私密性和完整性,防止中间攻击,钓鱼网站等

  • SSL由网景公司(Netscape)于1994年开发,最初用于保护网页浏览器和服务器之间的通信,但是它是一种私有协议,并且采用的是不安全的算法,如RC4(容易受到偏差攻击),DES(密钥过短),SHA-1(哈希碰撞)

  • TLS是SSL的标准化升级版,由IETF(互联网工程任务组)于1999年发布,修复了SSL的一些安全问题

    • 现在主流的TLS1.2采用的加密算法是AES,认证算法有RSA、ECDSA、DSA,密钥交换算法涉及RSA,DHE,ECDHE(后两者都能保证前向安全)

    • TLS1.3于2018年发布,目前正在被大力推广。支持的数字签名算法是ECDSA ,而弃用了1.2中支持的RSA签名,仅支持现代加密算法(如AES-GCM、ChaCha20-Poly1305、SHA-256),并且强制要求使用前向保密的密钥交换算法完全移除静态RSA密钥交换,防止解密历史流量。此外,它还简化了TLS的握手过程

  • 本文将主要介绍TLS1.2和TLS1.3协议的大致原理及通信过程

加密与认证

  • 对称加密即加密和解密都使用相同的密钥,这种加密算法速度快,但是如何让通信双方安全地共享同一个密钥是一个难题。如果该密钥被截获或者某一方泄露,都会导致通信过程中所有数据泄露,攻击者甚至可以进行中间人攻击。

  • 非对称加密则使用一对密钥(公私钥)进行通信,使用公钥加密的数据需要用私钥对密文进行解密,并且这种算法还可以用于签名,一般的场景为使用自己的私钥对消息哈希进行签名,其他人可以使用他的公钥进行验证,从而确保数据的来源。但是非对称加密算法速度慢,计算开销大,一般不适用于对实时性要求高的场景。

  • 通常的实践方式是结合对称和非对称的优点,使用非对称进行密钥(对称加密密钥)交换和签名,再使用对称加密实际的通信数据。

对称加密

对称加密在TLS协议中,主要用在握手阶段以后传输实际通信数据时,由于在握手阶段使用的公钥密码技术和密钥协商,可以确保协商得到的对称密钥是仅通信双方可知的安全密钥,而实际通信需要传输的数据量通常频繁且庞大,所以使用对称加密可以同时确保安全和效率。

AES

  • AES是一种分组密码,顾名思义,它将明文数据划分为固定大小的“块”(固定为128位长度),然后对每个块独立加密,生成密文块,并且该密文块长度和明文长度一致,都是128。解密的过程同样按块处理。并且加密和解密过程所使用的密钥必须是一样的,所以这种加密方式也是对称加密。

    image-20250722213519644

  • AES支持的密钥长度有128/192/256位,密钥越长当然加密强度越高,也就越难破解。但是不同的密钥长度也对应不同的加密轮数(每组数据都需要执行完整的加密轮数),以下是它们对应关系。

    AES 密钥长度(32位比特字) 分组长度(32位比特字) 加密轮数
    AES-128 4 4 10
    AES-192 6 4 12
    AES-256 8 4 14

    32位字指的是32位机中的word,其大小是32bit

  • 可能有读者好奇为什么要进行多轮的加密,其实这就是AES这种分组加密的精髓所在啦🤗。众所周知,密码的两大原则是混淆扩散,混淆是为了让密文与密钥的关系尽可能复杂,扩散是为了让明文单个位的变化影响密文多个位。AES的每一轮的计算过程都是为了实现这两个原则。

  • AES轮函数结构

    • 字节代换行移位列混合​轮密钥加

    • 字节代换:对消息矩阵中的每个元素进行非线性替换,代换矩阵为AES的“S盒”

    • 行移位:不改变消息矩阵的值,对每行做循环移位操作

    • 列混合:对消息矩阵的每一列按照GF(28)​矩阵乘法乘一个固定的多项式,得到的每个字节作为多项式的系数

    • 轮密钥加:将轮密钥矩阵和消息矩阵逐比特异或

      image-20250722215704886

非对称加密

RSA

  • rsa算法是目前使用最普遍的公钥加密算法之一。它的设计巧妙,也容易理解。该加密算法的安全性是基于一个数学事实:将两个大质数相乘很容易,但要将它们的乘积分解回原来的两个质数却极其困难,即大整数因子分解困难问题。为了便于理解rsa算法,需要先掌握以下几个数学基础:

    (1) 质数与互质

    • 质数:大于 1 的自然数,且只能被 1 和它本身整除。

    • 互质:两个数的最大公约数 (GCD) 为 1。例如 15 和 28 互质。

    (2) 模运算

    即求余数的运算,例如
    17mod5=2

    RSA 中大量使用模运算。

    (3) 欧拉函数 φ(n)

    表示在小于 n 的正整数中,与 n 互质的数的个数。

    • n 是质数,φ(n)=n1

    • n=p×q,且 p,q 均为质数,则

    φ(n)=(p1)(q1)

    这是 RSA 的关键公式之一。

    (4) 模逆元

    如果

    e×d1(modφ(n))

    d 叫做 e 在模 φ(n) 下的模逆元
    在 RSA 中,d是私钥的一部分,由 eφ(n)​ 计算得到(使用扩展欧几里得算法)。

  • 理解了以上数学基础以后,我们再来看rsa的密钥生成过程:

    选择两个大质数 pq

    计算 n=p×q

    计算 φ(n)=(p1)(q1)

    选择整数 e,满足 1<e<φ(n),且 eφ(n) 互质。通常选 65537。

    计算 d,使得 e×d1(modφ(n))

    公钥(e,n)
    私钥(d,n)

    如果只从数学原理上考虑,e和d是可以互换的。但在密码学应用中,考虑到性能和安全性是绝对不能互换的,加密和签名验证的过程使用的都是公钥,通常e是一个较小的值,而d的数量级与n相同,使用e作为公钥这样可以保证加密和签名验证的性能。从安全性上,虽然看上去已知(e,n)求d,和已知(d,n)求e都需要知道φ(n),而得到φ(n)的唯一方法是分解n得到p和q,这样看似难度都是大整数分解难题,但实际上由于d比e大得多,d包含的信息更多,存在高效的算法可以在仅知d,n的情况下分解n得到p和q。因此,e和d的地位绝对不能互换。

  • 有了公钥和私钥以后,便可以加解密了:

    • 加密(用公钥):
      明文 m(需 m<n),计算

      c=memodn

      得到密文 c。

    • 解密(用私钥):
      计算

      m=cdmodn

      可以证明m=m​,需要用到欧拉定理和中国剩余定理

  • 同理,有了公钥和私钥也就可以进行签名认证了。通常的方法是使用私钥对数据进行签名,将数字签名和原来的数据合并发送给对方,对方可以使用发送方的公钥来验证签名,从而实现对消息来源的认证。一般要发送的原始数据通常较大,所以为了降低计算量提高效率,会对数据的哈希值签名,而不是对数据本身签名。

哈希算法

  • 哈希算法也称摘要算法,主要用于对数据进行完整性校验。哈希算法将任意长度的输入通过散列算法变换成固定长度的输出,这个输出就是哈希值。

  • 一个理想的哈希算法需要具备以下特点:

    • 快速计算:能快速计算出任意数据的哈希值。

    • 抗碰撞性:很难找到两个不同的输入得到相同的输出。

    • 雪崩效应:输入的微小改变会导致输出的巨大差异。

    • 单向性:从哈希值反推原始输入在计算上是不可行的。

  • 以下简单介绍几种常见的哈希算法:

    MD5:固定输出长度128位(16字节)。已被证实不安全,可用于校验文件完整性

    SHA-1:曾是SSL/TLS等安全协议的基础,固定输出160位。已被证实不安全,不推荐用于任何安全场景。

    SHA-2家族:SHA-1的继任者,是一系列哈希函数的总称,包括 SHA-224, SHA-256, SHA-384, SHA-512 等(数字代表输出的比特长度)。其中 SHA-256 是目前最常用的。目前广泛使用且被认为是安全的。是比特币、现代SSL/TLS证书等众多安全应用的基础。

密钥交换

DH

  • DH密钥交换算法基于有限域的离散对数问题,它可以在不安全的网络中,通过交换一些公开的信息协商出共享密钥,使用此共享密钥建立安全通讯。

  • 核心数学基础是离散对数问题

    在有限域[1,p]中,p一般为一个很大的素数,g是有限域的生成元,

    gamodp=A

    已知g,a,p求解A非常简单;而根据g,p,A在[1,p]范围内求解a却非常的困难。

  • 以下是DH密钥交换的过程

    image-20250101123556707

    • 爱丽丝和鲍勃共有两个约定好的大数:一个素数 p 和一个生成元 a

    • 生成私钥:

      • 爱丽丝生成一个私密的随机数 SkA

      • 鲍勃生成一个私密的随机数 SkB

    • 计算公钥:

      • 爱丽丝计算她的公钥 PkA=aSkAmodp,并发送给鲍勃。

      • 鲍勃计算他的公钥 PkB=aSkBmodp,并发送给爱丽丝。

    • 计算共享密钥:

      • 爱丽丝收到 PkB 后,计算 S=PkBSkAmodp=(aSkB)SkAmodp=gSkASkBmodp

      • 鲍勃收到 PkA 后,计算 S=PkASkBmodp=(aSkA)SkBmodp=gSkBSkAmodp

    • 现在,爱丽丝和鲍勃都得到了相同的共享密钥 S,可以建立只有通信双方可以解密的安全信道了。而 p, a, PkA, PkB都是可以公开的,但只知道这四个值的人无法轻易计算出 S

DHE/ECDHE

  • DHE就是临时DH,其中的E是Ephemeral,它们的主要区别在于公钥/私钥对是长期使用还是每次会话都重新生成

  • DH的特点是长期使用同一对密钥,由于不需要在每次握手时都重新生成新的密钥对,所以计算开销较小。但是其缺乏前向安全性,即如果攻击者记录下了所有的通信数据,并且在未来的某个时间成功窃取了服务器的长期私钥,那么他就可以用这个私钥解密过去所有被记录的会话。

  • DHE的工作方式是,在每次TLS握手过程中,服务器(和/或客户端)都会临时地生成一对全新的、仅用于本次会话的DH密钥对。即便攻击者在未来窃取了服务器的长期私钥,也无法完整解密过去的通信。但缺点是计算开销大。

  • 现代密码学使用的都是ECDHE(椭圆曲线临时迪菲-赫尔曼),它兼具DHE所有优点,并具有更高的计算效率。ECDHE 已经成为现代TLS连接(如HTTPS)的事实标准。现在访问绝大多数主流网站,使用的都是基于ECDHE的密码套件(例如 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256

CA认证(PKI体系)

  • 结合上面的知识,至此对加密、签名、密钥协商已有了大致的了解。那么此时我们假设有以下这样的通信系统:服务器的公钥公开可查看,客户端向服务器发送请求后,服务器会返回它的公钥和DH密钥交换所需的参数及其数字签名,随后客户端使用公钥对数字签名进行验证,随后根据流程完成密钥协商获得共享对称密钥S,接着就可以用密钥S和服务器通信了。该流程存在一个致命缺陷,假设中对DH密钥交换参数的数字签名的验证只能确保信息在传输过程中未被篡改,而不能对服务器的身份进行认证,即客户端无法确定公钥就是目标服务器的。所以该流程在面对中间人攻击时将束手无措。

  • 因此引入PKI体系,该体系中存在一个重要的权威可信的第三方机构,证书颁发机构(CA)。在该体系下,服务器需要向CA申请数字证书,并提供域名/公网IP、长期公钥等基本信息,CA确定资产持有者身份以后会发放一个经CA数字签名的CA证书,其中包含:持有者信息、证书有效期、资产信息、服务器公钥和CA对证书内容哈希值的签名(用于验证证书真实性)

  • 但是仅是这样的话,客户端要验证证书真实性仍需要下载CA的公钥,虽然我们知道低级CA也有高级CA所颁发的证书,但依次向上验证终会要验证一个无人给其颁发证书的CA,这似乎又回到了原来的问题。总结来说,就是服务器的身份可以通过CA证书确定,但又因为无法确定最高级别CA的身份导致整条CA链不可信。

  • 最高级别的CA被称为根CA,为解决上述问题,根CA会生成一个自签名证书,该证书会被预装在操作系统或浏览器的信任库中,验证服务器身份时,只有当CA链中的根CA处于信任库中且整条链验证无误才能被认可。

  • 总结来说,CA证书建立了服务器长期公钥和服务器身份的联系,而长期公钥又用于验证密钥交换参数的来源,从而确保整个过程始终在与目标服务器通信。

  • CA信任链的构建和验证也存在不同的模型,以下小节将详细介绍

层次信任模型

在公共互联网中,只存在层次信任模型,在互联网(Web PKI)中,为了满足全球数十亿设备自动、无缝互连的需求,通过“全球预装统一信任列表”的方式,将复杂的跨信任域问题简化为一个事实上的“全球层次信任模型”。在各种操作系统和浏览器软件中都预装了认可度高的公开根CA自签证书。交叉和桥CA模型只有在少数私网场景中使用。

  • 层次信任模型是PKI体系中基本的信任模型,也是最常见的信任模型。只要通信双方均处于同一根CA的信任域内,即适用该模型。对于客户端访问服务器的场景来说,只要服务器所处的信任域的根CA的自签名证书已经预装在客户端了,通过逐级验证可证明服务器是可信的。所有用户需要预装根CA的自签名证书,并将其标记为信任锚。

  • 该模型是严格的自顶向下的树状结构,单向信任(即下级绝对信任上级,信任路径单一,不能横向建立信任)。该体系有且仅有一个根CA作为信任锚,根CA可以授权多个子CA,子CA还可以进一步授权。验证证书时都需要从根CA逐级向下验证,即便由同一个子CA颁发证书的两个用户也不能直接信任。

  • 如下图,虽然用户A和C都由子CA4颁发证书,但A要验证C时仍需要通过根CA的公钥验证CA4的证书,证明可信后再用CA4的公钥验证用户C的证书。

  • 如果用户B给A发了一条带数字签名的消息,用户A要验证该消息签名的真实性,其过程如下:

    1. 用根CA的公钥验证CA1的证书,提取CA1的公钥

    2. 用CA1的公钥验证CA3的证书,提取CA3的公钥

    3. 用CA3的公钥验证用户的证书,提取用户B的公钥

    4. 用用户B的公钥验证消息的签名

image-20251207202309185

  • 下图是真实互联网中一条完整的证书信任链展示,通常情况下,服务端不会向客户端发送根CA自签名证书,因为该证书体积较大,且全球通用,一般在操作系统或浏览器中已经预装,没有必要重复发送。

    image-20251207221954014

交叉信任模型

  • 一般场景下,层次信任模型完全够用。但一些私有场景存在两个层次信任模型不互通的情况,导致两个体系之间互不信任。例如每个公司有其独立的层次信任体系,当两个公司由于商业合作需要访问对方体系内的服务时,可让两个根CA互相签发证书来构建交叉信任模型解决互不信任的问题。

  • 该模型的结构特点:两个或多个CA互相为对方签发证书(交叉证书),承认对方的用户在其信任域内有效。可以形成网状结构,没有统一的顶级根CA。

  • 以下图为例,根CA1和根CA2互相签发证书,这样两个体系之间的用户就可以互相信任。例如用户 Y 可以信任用户 J 证书。信任链为根 CA2——根 CA2(1)——根 CA1——子 CA12——用户 J 证书

网络安全(1) Image[4]

桥CA信任模型

  • 通过设立一个中立的、专门的桥CA作为信任枢纽。桥CA本身不向最终用户颁发证书。各个独立的信任域(可以是层次型、交叉型或其他类型)的CA分别与桥CA进行交叉认证。通过桥CA这个“翻译官”或“交换机”,所有连接到桥CA的信任域之间就间接建立了信任。

  • 证书验证路径:从一个域的终端证书,追溯到其域内CA,跳转到桥CA,再跳转到目标域的CA,最后验证目标证书。

  • 以下图为例,还是用户Y要验证用户J的证书:根CA2——桥CA(2)——桥CA——根CA1(q)——根CA1——子CA12——用户J证书

桥ca Image[4]

TLS握手

TLS 1.2

  • 下图是在真实网络环境中捕获的TLS1.2握手流程的数据包

image-20251208160431678

  • 下方流程图是TLS 1.2版本的握手流程,该版本握手流程需要两个往返时延才能建立加密通信通道。下面结合该流程图对上面捕获的数据包进行逐包解释。

    image-20251208225325837

  • 包1:Client Hello

    • 该包表示客户端向服务器发起TLS连接请求

    • 包含的主要内容

      image-20251208162348718

  • 包2:Server Hello, Certificate...

    • 服务器将Server Hello、Certificate、Server Key Exchange、Server Hello Done多个握手消息合并为一个TCP数据包发送给客户端。

    • Server Hello部分:主要用于确定选用的加密套件和用于协商对称密钥的随机数Rs。TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384表示密钥交换使用ECDHE_RSA,身份认证使用RSA,批量加密算法使用AES_256_GCM,消息认证码算法使用SHA384

      image-20251208163218380

    • Certificate部分:发送证书链供客户端校验身份

    • Certificate Status:该部分显示证书状态,即是否处于有效期内

    • Server Key Exchange部分:服务器发送密钥交换所需的临时公钥。Curve Type和Named Curve字段中的是密钥协商所需要用到的椭圆曲线。Pubkey是服务器生成的临时椭圆曲线公钥。下面的Signature部分是服务器用自己的长期私钥对上述参数进行的签名,用来防止中间人攻击。

      image-20251208165756347

    • Server Hello Done:服务端告诉客户端“我话讲完”

  • 包3:Client Key Exchange, Change Cipher Spec...

    • 同样地,客户端也将多个消息合并为一个TCP数据包发送给服务端

    • Client key Exchange:发送客户端生成的用于密钥交换的公钥

      image-20251208170953111

    • Change Cipher Spec: 这是一个信号,表示此时客户端已计算出协商的对称密钥,并会使用该密钥对本次会话后续的所有内容进行加密。

    • Encrypted Handshake Message (Finished): 发送一段加密的握手校验数据,验证加密通道是否工作正常。

  • 包4:Change Cipher Spec, Finished

    • 服务端收到Client key Exchange后,也可以计算出协商的对称密钥。

    • 内容: 服务器也发送 Change Cipher Spec 和自己的 Finished 消息。至此,双方确认握手成功。

TLS 1.3

  • 下图是TLS 1.3握手数据包

image-20251208110014179

  • 该版本握手流程相较于1.2版本进行了简化,只需要一个往返时延就能够建立加密通信通道。对于TLS1.3,就不在进行逐包分析,主要介绍以下相较于1.2版本的差异:

    • Key Share:1.3 客户端在第一步就把密钥交换的参数直接带上了。

    • 服务端在接收到该数据包的一瞬间,就已经拥有了计算共享密钥所需的全部信息:客户端的临时公钥(Client Key Share)、服务端的临时私钥(服务端本地生成)。因此,除了 Server Hello 这一消息必须明文传输(用于协商协议版本和算法)外,后续的所有握手消息都会被加密。在Wireshark 抓包中,将无法找到明文的服务器证书、证书验证以及最后的握手校验消息

    image-20251208225407574

ESNI/ECH

  • 由于真实网络环境中,在服务器前方通常都会设置反向代理,很多时候存在多个服务器使用同一个反向代理,即出现一个IP地址托管多个网站的情况。此时,反向代理服务器需要知道客户端想要访问的是哪个域名,才能提供正确的SSL/TLS证书和建立正确的连接。为解决该问题,客户端需要在Client Hello数据包中,通过 SNI 字段直接告知想要访问的服务器域名。

  • 但在TLS1.2及1.3版本的默认标准中,SNI字段都是明文传输的,这导致中间设备(防火墙、运营商)可以轻易看到你正在访问哪个网站,并据此进行阻断或流量分析。

  • ESNI和ECH是为了解决SNI明文传输引起的隐私问题的尝试。客户端会根据DNS查询的SVCB记录和TXT记录来判断使用SNI/ESNI/ECH中的其中一种方式访问目标。

ESNI

  • 原理:

    • DNS 联动:服务器将自己的公钥发布在 DNS 记录中(通常通过 TXT 记录)。

    • 提前加密:客户端在发起 TLS 连接前,先通过 DNS(如DNS over HTTPS)获取服务器公钥,然后用该公钥加密 SNI 字段。

    • 传输:握手时,Client Hello 包中的 SNI 变成了一段乱码,只有目标服务器能解密。

  • 局限性:

    • 元数据暴露:虽然域名加密了,但 Client Hello 中其他字段(如扩展列表、密码套件)仍是明文的,这些“指纹”可能依然会暴露目标。

    • 不够全面:它仅加密了 SNI,没有保护整个握手协商过程。

ECH

Encrypted Client Hello - 隐私的最后一个组成部分

  • ECH 是 ESNI 的升级版,也是目前的最终解决方案。

  • 原理: ECH 不再只加密 SNI 字段,而是将整个 Client Hello 数据包分为两部分:

    • Outer Client Hello (外层):明文传输,包含一个“迷惑性”的通用域名(如 Cloudflare 的公共域名),用于引导流量。

    • Inner Client Hello (内层):包含真正的域名(SNI)和其他敏感参数,全部使用从 DNS 获取的服务器公钥进行全包加密

  • 核心优势:

    • 完全隐私:中间人只能看到外层的通用域名,无法识别用户真正的访问意图。

    • 指纹混淆:消除了由于 TLS 握手特征产生的设备指纹识别。

    • 依赖:必须配合 HTTPS DNS 记录 以及 DoH (DNS over HTTPS) 使用,否则 DNS 查询阶段就会泄露域名。

img

上一篇