网络安全
计算机网络安全的目标:
- 保密性:只有发送方和接收方能够理解传输报文的内容,即便窃听者可以截获报文,他也无法获取出信息,这要求报文必须在一定程度上进行加密(encrypted)
- 端点鉴别:信息的发送方和接收方需要能够相互鉴别对方的真实身份,以确信通信的另一方确实具有其所声称的身份
- 报文完整性:无论何种方式收到的信息,无论是否已确认发送方的身份是否真实,无论信息是否是经过加密传输的,我们依然需要确认所收到的信息都是完整的,没有被纂改或伪造
- 运行安全:需要能保障系统或服务持续可用,并能抵御攻击和访问控制。核心是防止拒绝服务攻击和系统入侵,维持正常运行状态。
密码学基础
密码学技术使得发送方可以伪装数据,使截获者不能从截取到的数据中获得任何信息,当然,接收方必须能够从伪装的数据中恢复出初始数据。此外,密码学技术能提供端点鉴别、报文完整性、不可否认性等安全保障。
加密的实现方式
对称密钥加密(Symmetric Encryption)通常主要分为两大类:
- 分组密码(Block Cipher):通过将明文划分为固定大小的数据块,然后进行轮函数、S盒替换、置换、多轮迭代等运算方式对每个分组进行加密,一次加密一整组数据。其核心目标是实现“混淆(Confusion)”与“扩散(Diffusion)”,使明文与密文之间的关系高度复杂。现代互联网中广泛使用的AES属于该类型,早期常见算法还有DES、3DES。分组密码通常用于TLS、磁盘加密、VPN、Wi-Fi等场景
- 流密码(Stream Cipher):不对数据进行固定分组,而是通过伪随机算法持续生成“密钥流(Keystream)”,再与明文按位或按字节进行XOR异或运算,实现一次加密一个比特或字节的数据流。该方式延迟低、速度快,适合实时通信场景。早期常见算法有RC4(现已不安全),现代常见算法有ChaCha20、Salsa20。流密码广泛用于TLS、移动设备、无线通信等领域。
非对称密钥加密(Asymmetric Encryption/Public-Key Cryptography)采用“公钥 + 私钥”这一非对称结构:公钥是公开的,通常用于加密或验证签名,私钥仅由持有者保存,通常用于解密或生成数字签名(当然它们也可以反过来使用)。其安全性通常基于大整数分解、离散对数、椭圆曲线等数学难题,而不是分组轮函数结构。常见算法包括 RSA、Diffie-Hellman、Elliptic Curve Cryptography。由于运算开销较大,非对称加密通常不直接用于大量数据加密,而主要用于密钥交换、身份认证、数字签名、HTTPS/TLS握手等场景。
分组加密的思想
块密码
块密码(Block Cipher)的目标是实现一种“看起来完全随机”的可逆映射,理论上,它可以通过一个映射表来完成加密。在块密码中,要加密的报文被分割为k比特的块,每块被独立加密。为了加密一个块,密码采用了一对一映射,将k比特块的明文映射为k比特块的密文。如:假设k=3,建立一张映射表:
| 输入 | 输出 | 输入 | 输出 |
|---|---|---|---|
| 000 | 110 | 100 | 011 |
| 001 | 111 | 101 | 010 |
| 010 | 101 | 110 | 000 |
| 011 | 100 | 111 | 001 |
它总共有23=8种输入/输出,由此报文010110001111可以被加密为101000111001。映射关系(表)是可以修改的,一共会有8!=40320种不同映射(比如000不再映射为110,而是映射为010或其他)。
通过暴力尝试,现代PC可以很快完成这40320尝试,找到当前密文使用的映射关系表,从而解密出加密报文,为了阻止暴力破解,块密码的k值通常会使用很大的值,如64位甚至更大,可能的映射关系将增长为2k!种,加大了暴力破解难度。但对于发送方和接收方,他们也需要维护一张具有264个输入值的表,并需要通过查找表来加密/解密报文,当需要改变密钥时还需要重新生成该表,这些操作工作量十分庞大,因此通过全表块密码来加密/解密报文几乎不可能。
块密码通过函数加密

通过一个巨大查找表来实现加密不太可能,因此现代块密码通常使用“多轮函数”来模拟随机排列表,上图是这类函数的一个示例,以64位输入为例:
- 函数首先会将64比特块划分为8个块,每个块由8比特组成
- 每个8比特块由一个“8比特到8比特”表处理,这是个可管理的长度,映射表不会太大,这类表又称为S盒(Substitution Box)。如:第一个块由标志为T1的表来处理并映射
- 这8个块的输出会经过置换(Permutation)、移位、混合等操作,重新新装配成一个64比特的块,该输出会被回馈为64比特的输人,开始第二次循环
- 经过多轮循环后,输入数据会产生雪崩效应(Avalanche Effect),使得每个输人比特影响最后输出比特的大部分(即使不是全部),即便只改变1个输入比特,也可能导致最终密文的大部分比特发生变化,这样可以让明文与密文之间的关系高度复杂化
- 经n次这样的循环后,该函数将输出一个64比特的密文块作为加密结果
- 块密码要求整个过程“可逆”,因此S盒、置换等操作都必须存在逆操作。加密时执行多轮变换,解密时则按相反顺序执行逆变换,从而恢复原始明文
- 密钥的作用:进行加密/解密时,主密钥会被扩展为多个每一轮需要参与运算的轮密钥(Round Key),这些密钥会影响:
- S盒或内部函数的具体行为
- 每轮的数据混合方式
- 作为函数输入,成为最终密文/明文某些字节的源数据之一
- 加密算法本身通常是公开的,且算法流程固定,密钥同时作为控制因子和输入数据来源,会影响加密算法在每一轮中的具体运算结果
- 一些曾经流行的块密码(如:DES、3DES、AES)标准都使用了函数(而不是预先确定的表)来完成加密,这些算法也都使用了比特串作为密钥,如,DES使用56位密钥,输入数据块长64比特。AES使用128比特块,支持128/192/256比特长的密钥
- 暴力破解:若密钥长度为 n 比特,则理论上存在2n种可能密钥,攻击者需要枚举所有可能密钥并尝试运算解密,因此选择越长的密钥,越好的加密算法往往能带来更好的加密保障。如:用1秒破解56比特DES的计算机(每秒尝试256个密钥)来破解一个128比特的AES密钥,要用大约149万亿年的时间才有可能成功
CBC密码块链接
实际应用通常要加密一个长报文(或长数据流),如果将报文切都割成k比特块,并独立地加密每块,会出现一个问题:两个或多个明文块内容相同时,块密码执行相同的操作将产生相同的密文。当攻击者看到相同的密文块时,他们可能能够潜在地猜出其明文,甚至还原出整个报文的大致内容框架。解决这个问题的方法是,为每一个明文块m(i)生成一组随机数据r(i),把异或后的结果加密生成密文c(i)=ks(m(i)⊕r(i)),发送方将密文和随机数据一起发送给接收方,然后恢复出明文。这样可以使相同的明文块由于随机数据的存在,产生不同的密文块,但为每一个块都添加随机数据会极大地增加报文大小。
为此,块密码通常使用一种称为密码块链接CBC(Cipher Block Chaining)的技术。其基本思想是仅随第一个报文发送一个随机值,让每个块的加密结果依赖前一个块,CBC的具体运行流程:
- 在加密报文之前,发送方生成一个随机的k比特串,称为初始向量IV(Initialization Vector)。将该初始向量表示为c(0),发送方以明文方式将IV发送给接收方。
- 对第1个块,发送方通过
c(1)=ks(m(1)⊕c(0))计算出密文块 - 对第2个块,发送方通过
c(2)=ks(m(2)⊕c(1))计算出密文块 - 对于第i个块,发送方计算并发送密文
c(i)=ks(m(i)⊕c(i-1)) - 即每个块的加密结果依赖前一个块,而不是为所有块都生成随机数据
CBC的缺点
虽然CBC能解决同一明文会被加密为同一密文的问题,但它后一个块的加密/解密依赖于前一个块的特点,带来了以下问题:
- 无法并行加密/解密,现代CPU非常强调并行流水线,而CBC天然限制吞吐
- 无法直接独立解密某一块,一旦某一个密文块损坏,后续块都无法解密
- 无法保证数据没有被篡改,攻击者依旧可以修改某些密文bit,让接收者解密的部分明文发生变化
因此,现代密码学不再主流使用CBC(TLS1.3已移除CBC,OpenSSH 默认不用CBC),而是推荐使用AEAD(Authenticated Encryption with Associated Data,带关联数据认证的加密)方案,它能一体化解决加密、报文完整(防篡改)、身份鉴别问题
两类密码体制
对称密钥密码体制
对称密钥体制又称为单钥体制,加密和解密使用同一个密钥,对称密钥体制中密钥 K(key)是需要保密的,而加密算法E和解密算法D是公开的,它的加密模型可以简单表示为:
- 加密:发送端使用密钥 K 和加密算法 E 加密明文 X,生成密文 Y,即:
Y = Ek(X) - 解密:接收端通过解密算法 D 和密钥 K 解出明文 X :
Dk(Ek(X)) = X
对称密钥密码体制的应用
对称密钥体制通常分为分组加密和流密码加密两类,使用分组密码的有:
- DES:由IBM设计,1977年被美国采纳为联邦数据加密标准,后被ISO作为数据加密标准。DES会将明文划分为64位分组进行加密,密钥长度名义上为64位,但其中8位用于奇偶校验,实际安全强度仅56位。由于现代计算机已能够较快完成56位密钥暴力破解,DES现已不再安全。
- 3DES(Triple DES):为延长DES寿命而提出,其核心思想是对数据连续执行三次DES运算,以提高密钥强度。常见方案使用两个或三个56位DES密钥,安全性明显高于DES,但计算速度较慢。随着现代算法的发展,3DES已逐渐被AES取代,并被认为不适合长期使用
- AES:当前最主流的分组加密算法,由比利时密码学家 Joan Daemen 与 Vincent Rijmen 设计(Rijndael算法),2001年成为美国新一代加密标准。AES采用SPN(替换-置换网络)结构,支持128/192/256位密钥,分组长度固定为128位,兼具高安全性与高性能,广泛应用于HTTPS/TLS、VPN、磁盘加密、Wi-Fi等领域
使用流密码的有:
- RC4:曾经极其流行的流密码,由 Ron Rivest 设计,核心思想是通过内部状态机不断生成伪随机密钥流,并与明文进行XOR异或运算。RC4实现简单、速度快,曾被广泛用于SSL/TLS与Wi-Fi(WEP)等协议,但后续发现存在严重统计偏差与密钥流漏洞,目前已基本淘汰。
- Salsa20:由密码学家 Daniel J. Bernstein 设计,强调高性能与抗侧信道攻击能力。它通过ARX(加法、循环移位、异或)结构生成密钥流,避免复杂S盒操作
- ChaCha20:Salsa20改进版本,目前是现代主流流密码之一。ChaCha20在软件平台尤其是移动设备上性能优秀,并具备较强安全性,通常与Poly1305消息认证算法组合为ChaCha20-Poly1305,被广泛用于TLS、VPN、SSH、移动通信等场景
公钥密码体制
公钥密码体制又称为公开密钥密码体制,其特点是加密和解密使用不同的密钥,其概念由斯坦福(Stanford)大学的研究人员Diffie与Hellman于1976年提出,因此其密钥交换算法也称为Diffie-Hellman密钥交换。公钥密码体制的产生主要出于两个原因,一是由于对称密钥密码体制存在密钥分配问题,二是由于对数字签名的需求。
在公钥密码体制中,公钥PK(publickey)是向公众公开的,而私钥SK(secret key,又称秘钥)则是需要保密的,同时加密算法E和解密算法D也都是公开的。它的加密模型为:
- 发送者A要向B发送报文前,要用B的公钥 PKB通过加密算法 E 加密报文,得出密文 Y :
Y = EPKB(X) - 接收者B用自己的私钥 SKB通过解密算法解密,恢复出明文:
D SKB(Y) = DSKB(EPKB(X))= X - 公钥加密的密文不能使用公钥来解密
- 从算法上,对X先进行D运算再进行E运算,和对X先进行E运算再进行D运算是一样的
公钥密码体制的应用
- RSA:1977年由 Ron Rivest、Adi Shamir、Leonard Adleman 提出,是最经典的公钥密码体系之一。其安全性基于“大整数分解困难问题”,支持加密、数字签名与密钥交换。RSA长期广泛用于HTTPS/TLS、数字证书、软件签名等场景,但由于计算开销较大,现代系统中更多用于密钥交换与签名,而非直接加密大量数据
- ECC(Elliptic Curve Cryptography):基于椭圆曲线离散对数问题的公钥密码体系。相比RSA,ECC在相同安全等级下可使用更短密钥,因此性能更高、带宽占用更低,尤其适合移动设备与嵌入式系统。现代TLS、数字签名、加密货币等系统广泛使用ECC
- Ed25519:基于椭圆曲线Curve25519的现代数字签名算法,由Daniel J. Bernstein等人设计。其特点是高性能、高安全性、实现简单,并具备较好的抗侧信道攻击能力,现已广泛用于SSH、Git签名、加密通信等场景
- 后量子密码(Post-Quantum Cryptography):用于应对未来量子计算机可能对RSA、ECC等传统公钥体系带来的威胁。当前主流研究方向包括格密码、哈希密码、多变量密码等,美国国家标准与技术研究院(NIST)已开始推进相关标准化工作
哈希
密码散列函数(cryptographic hash function),简称哈希函数(Hash)或散列函数,是一种将任意长度的数据映射为固定长度摘要的算法,其核心思想是通过数学变换对输入内容进行“数字指纹”提取,其输出结果通常称为哈希值(Hash Value)、摘要(Digest)或散列值,哈希函数有以下特点:
- 哈希函数的输入空间无限大,而输出空间有限(如:SHA-256有2256种输出),把无限的输入映射到有限输出,必定存在不同输入有相同输出(碰撞),因此哈希本质上属于多对一映射,因此MD5、SHA-1等算法已因可被有效构造碰撞而失效,但对于SHA-256、SHA-3等现代哈希算法,以现代计算机计算机的算力很难主动构造/伪造出与目标哈希值一致的输入,因此它们依旧安全可用
- 输入发生微小变化时,输出会产生巨大差异(雪崩效应)
- 它是一种单向函数,根据哈希值几乎不可能反推出原始数据
常用的哈希函数
- MD5:即Message Digest(报文摘要)的第5个版本,哈希值长度128位。其核心思路是将数据按512位分组,多轮执行非线性函数、位运算与循环移位,不断更新内部状态,最终生成128位摘要。运算速度快,曾广泛用于文件完整性校验与密码存储,但已能被有效构造碰撞,因此不再适用于安全场景
- SHA-1(Secure Hash Algorithm 1,安全散列算法1):由美国NSA设计,输出160位哈希值。整体结构与MD5类似,同样采用分组、迭代压缩和多轮混淆运算,但安全性高于MD5。后来研究者已实现实际碰撞攻击,因此也被逐渐淘汰
- SHA-2:SHA系列第二代算法,包括SHA-224、SHA-256、SHA-384、SHA-512等。其核心仍是“分组 + 多轮压缩”的Merkle–Damgård结构,但内部运算更复杂,抗碰撞能力远强于MD5和SHA-1。其中SHA-256最为常见,输出256位哈希值,目前仍被广泛用于TLS、数字签名、区块链等领域
- SHA-3:SHA系列第三代算法,基于Keccak算法设计,与SHA-1、SHA-2采用完全不同的海绵结构(Sponge Construction)。它通过“吸收数据”和“挤出结果”的方式生成哈希值,具有更强的结构独立性,即使SHA-2未来出现问题,也能作为替代方案
- CRC:循环冗余校验(Cyclic Redundancy Check),严格来说并不属于密码学哈希函数。它主要通过多项式除法检测数据传输中的随机错误,运算速度极快,广泛用于网络通信、磁盘与文件校验。但CRC不具备抗碰撞与抗伪造能力,无法用于安全领域
MD5算法工作流程
很多散列函数的工作流程和MD5类似:
- 长度追加:MD5首先统计原始报文长度,并将其对264取模后的结果(64位长度值)追加到报文尾部。这样做是为了让算法能够感知原始数据长度,避免部分填充攻击
- 数据填充:在报文和余数之间填充1~512位数据,使得填充后的总长度是512的整数倍。填充的首位是1,后面都是0
- 分组处理:将填充后的数据划分为多个512位数据块。MD5内部维护4个32位状态寄存器(A、B、C、D),总共128位,它们会随着每个数据块的处理不断更新
- 压缩计算:每个512位数据块会被进一步划分为16个32位小块,并经过4轮、共64步的非线性运算,包括位运算、模加、循环移位等操作。每轮计算都会将“当前数据块”与“当前128位状态值”混合,并影响这128位状态值的结果
- 迭代压缩:前一个数据块计算得到的128位状态值,会作为下一个数据块的输入状态继续参与运算。因此无论输入数据多长,算法始终只保留一个固定大小的128位内部状态值
- 输出摘要:所有数据块处理完成后,最终得到的128位状态值,就是MD5报文摘要
报文鉴别
报文鉴别的特点:
- 验证通信的对方的确是自己所要通信的对象,而不是其他冒充的人
- 验证传送的报文是完整的,没有被他人篡改过
- 不提供报文的加密
- 通常使用共享的对称密钥,运算速度快,一般只确认报文是拥有密钥的主机发送(不具体管谁),因此不提供不可否认性
报文鉴别码MAC
发送报文时,为了方便校验报文是否被篡改,发送方可以将报文的哈希附加在报文后一起发过去,但中间人也可以修改报文后生成新的哈希值,并替换掉原来的哈希值来完成纂改。这就要求发送方和接收方拥有一个共享密钥,称为鉴别密钥
(authentication key),并通过以下方式防止纂改:
- 发送方将报文内容与密钥进行混合,然后进行哈希生成报文鉴别码(Message Authentication Code,简称MAC,又称消息认证码)
- 接收方通过同样的算法混合报文和密钥,并同样进行哈希进行校验
- 中间人没有密钥,即便修改报文和哈希值,他计算的结果也不会和接收者最终一致
- 报文鉴别码MAC的生成还可以通过加密函数等方法实现
因此,报文鉴别码MAC是一种用于验证通信消息完整性和真实性的密码学工具。它通过通信双方共享的密钥对消息进行算法处理,生成一段固定长度的短数据(即MAC值),并将其附加在消息中一起发送,有效防止消息在传输过程中被篡改或伪造
主流报文鉴别方案
- HMAC(Hash-based Message Authentication Code):一种基于哈希函数与共享密钥实现的消息鉴别算法,其核心思想是将共享密钥按特定结构与报文混合,然后进行多轮哈希运算,生成消息鉴别码(MAC)。它能够验证消息完整性与发送者身份,但不具备不可否认性。HMAC 计算效率高、实现简单、适合网络环境,是现代最主流的消息鉴别方案之一,广泛用于 TLS、SSH、JWT、OAuth、云服务 API 签名等场景
- CMAC(Cipher-based Message Authentication Code):一种基于分组密码实现的消息鉴别算法,通常基于 AES 构建。其核心思想是利用共享密钥对分组数据进行链式加密运算,并生成固定长度的鉴别码。CMAC 不依赖哈希函数,适合硬件实现,在嵌入式设备、智能卡、物联网、工业控制等场景中应用广泛
- Poly1305:一种高性能消息鉴别算法,由 Daniel J. Bernstein 设计。其核心思想是利用一次性密钥对消息进行有限域上的多项式运算生成鉴别码。Poly1305 计算速度极快,软件实现效率高,并具备良好的抗侧信道攻击能力,通常与 ChaCha20 组合为 ChaCha20-Poly1305,广泛用于 TLS 1.3、QUIC、WireGuard 等现代安全协议
数字签名
数字签名兼具报文鉴别的功能,保证以下功能:
- 身份确认:接收者能够核实发送者对报文的签名,确信该报文的确是发送者发送的,且其他人无法伪造对报文的签名
- 确认报文完整性:接收者确信所收到的数据和发送者发送的完全一样,没有被篡改过
- 不可否认:发送者签名后后不能抵赖对报文的签名
数字签名的实现
数字签名主要基于公钥算法实现,其核心流程与特点如下
- 发送方(签名者)使用自己的私钥对报文进行签名,接收方使用对应的公钥来验证签名的有效性
- 签名和验证本质上是进行加密/解密运算,它们只是一组数学运算,由于目的不是加密,因此甚至可以是对明文进行解密运算来作为签名
- 对于长报文通过加密/解密进行验证运算量太大,因此通常不对原报文进行签名,而是先对原报文执行哈希,然后对哈希值签名/验证
- 由于只有签名者持有私钥,因此完成签名的有效性验证后,签名者无法否认该报文的签名
主流数字签名方案
- RSA签名:基于RSA公钥密码体制的早期数字签名方案,其核心思想是对报文摘要进行RSA私钥运算生成签名,再通过公钥验证。RSA是最早被广泛应用的公钥签名体系之一,广泛用于早期 HTTPS/TLS、数字证书、软件签名,但密钥与签名体积较大、运算效率较低,存在潜在攻击风险,因此已逐渐被 RSA-PSS 替代
- RSA-PSS(RSA Probabilistic Signature Scheme):RSA 的现代安全签名模式,通过在签名过程中加入随机填充(PSS)增强安全性。相比传统RSA签名,其具有更严格的安全性证明与更强的抗攻击能力,目前已成为RSA推荐签名标准,广泛用于现代TLS、CA证书体系、代码签名与操作系统更新验证
- DSA:(Digital Signature Algorithm):专门为数字签名设计的算法,基于离散对数问题的传统数字签名算法,由美国 NIST 制定为联邦数字签名标准。其核心思想是在有限域乘法群中生成随机化签名并使用公钥验证。DSA 曾广泛用于政府与早期互联网安全系统,但由于效率、参数与实现限制,现代已基本被 ECDSA与 EdDSA取代
- ECDSA(Elliptic Curve Digital Signature Algorithm):基于椭圆曲线离散对数问题的数字签名算法,可视为 DSA 在椭圆曲线体系上的扩展。相比 RSA 与传统 DSA,其在相同安全等级下具有更短密钥、更小签名与更高效率,因此成为现代互联网最主流的数字签名方案之一,广泛用于 HTTPS/TLS、区块链、数字证书、移动设备与加密货币系统
- Schnorr签名(Schnorr Signature):基于离散对数问题的数字签名方案,由 Claus Schnorr 提出。其数学结构相比 ECDSA 更简单,具有良好的可证明安全性,并天然支持签名聚合、多重签名等高级特性。现代区块链系统(如比特币 Taproot)已开始采用 Schnorr 签名,以提升隐私性与链上效率
- EdDSA(Edwards-curve Digital Signature Algorithm):基于 Edwards 曲线的一类现代数字签名框架,其核心思想是使用确定性签名流程避免传统 ECDSA 对随机数质量的强依赖。EdDSA 具有高性能、高安全性、实现简单、抗侧信道攻击能力强等特点,被认为是现代工程实现质量较高的签名体系之一
- Ed25519:EdDSA 最主流的具体实现之一,基于 Curve25519 椭圆曲线,其特点是签名速度快、验证效率高、实现安全性强,并默认避免 ECDSA 中因随机数问题导致私钥泄露的风险。现已广泛用于 SSH、Git 签名、WireGuard、Signal、加密通信与现代身份认证系统等场景
端点鉴别
端点鉴别(end-point authentication)又可称为实体鉴别,指一个实体经过计算机网络向另一个实体证明其身份的过程,如客户端向某个电子邮件服务器证明其身份。实体鉴别和报文鉴别不同。报文鉴别是对每一个收到的报文都要鉴别报文的发送者,而端点鉴别是在系统接入的全部持续时间内对和自己通信的对方实体只需验证一次,流程为:
- A 使用共享对称密钥 K 加密自己的身份信息发送给B,B收到此报文后,用共享对称密钥K进行解密,从而鉴别了实体A的身份
- 该过程中,中间人C可能截获A发送的报文(不需要破译报文),并在其他时间重放该报文,通过B的鉴别
因此端点鉴别核心是要通过不重数(nonce)来防重放攻击(replay attack),不重数指在一个协议的生存期中只使用一次的大随机数,利用不重数可以鉴别出旧请求和新请求:
- A发送其身份和一个明文不重数Ra给B,随后B响应A的查问,用共享的密钥K对Ra加密后发回给A,同时也给出了自己的不重数Rb。最后,A再响应B的查问,用共享的密钥K对Rb加密后发回给B,以此完成端点鉴别并防止重放攻击
- 在使用公钥密码体制时,可以对不重数进行签名来完成端点鉴别。B用其私钥对不重数RA进行签名后发回给A。A用B的公钥核实签名,如能得出自己原来发送的不重数RA,就核实了和自己通信的对方的确是B。同样,A也用自己的私钥对不重数Rb进行签名后发送给B。B用A的公钥核实签名,鉴别了A的身份。
密钥分配
由于密码算法是公开的,网络的安全性就完全基于密钥的安全保护上,
密钥分配(或密钥分发)是密钥管理中最核心的问题
对称密钥的分配
对称密钥的分配要解决以下问题:
- 如果n个人中的每一个需要和其他n-1个人通信,一共需要n(n-1)个密钥。如果每两人共享一个密钥,需要的密钥数是m(n-1)/2。如果n是个很大的数,所需要的密钥数量就非常大。
- 通信的双方如何在互联网中安全传输密钥
目前常用的密钥分配方式是设立密钥分配中心KDC(Key Distribution Center)。KDC的任务是给需要进行加密通信的用户临时分配一个会话密钥(仅使用一次)。如:假定用户A和B都是KDC的登记用户。A和B在KDC登记时就已经在KDC的服务器上安装了各自和KDC进行通信的主密钥(master key)KA和KB。密钥分配分为三个步骤:
- 用户A向密钥分配中心KDC发送时用明文,说明想和用户B通信。在明文中给出A和B在KDC登记的身份
- KDC用随机数产生“一次一密”的会话密钥KAB供A和B的这次会话使用,然后向A发送回答报文。这个回答报文用A的密钥KA加密。这个报文中包含这次会话使用的密钥KAB和请A转给B的一个票据(ticket),该票据包括A和B在KDC登记的身份,以及这会话将要使用的密钥KAB。票据用B的密钥KB加密,A无法知道此票据的内容
- 当B收到A转来的票据并使用自己的密钥KB解密后,就知道A要和他通信,同时也知道KDC为这次通信所分配的会话密钥KAB
- 此后,A和B就可使用会话密钥KAB进行这次通信了
- KDC 还可在报文中加入时间戳,以防止报文的截取者利用以前已记录下的报文进行重放攻击。会话密钥KAB是一次性的,因此保密性较高。而KDC 分配给用户的密钥KA和KB,都应定期更换,以减少攻击者破译密钥的机会。
Kerberos密钥分配协议
Kerberos是由MIT开发的密钥分配协议,它既是鉴别协议,同时也是KDC,使用AES加密算法保障加密安全,被广泛用于企业内网、Windows域环境、和部分Unix/Linux基础设施中,以下是Kerberos V4的大致工作过程:
Kerberos使用两个服务器:鉴别服务器AS(Authentication Server)和票据授子服务器TGS(Ticket-Granting Server),假设A是请求服务的客户,B是被请求的服务器,A通过Kerberos向B请求服务,Kerberos需要先鉴别A的身份,然后向A和B分配会话使用的密钥:
- A用明文(包括登记的身份)向鉴别服务器AS表明自己的身份。AS存储了各实体登记的身份及其口令,AS对A的身份进行验证。只有验证结果正确,才允许A和票据授予服务器TGS进行联系。
- 鉴别服务器AS向A发送用A的对称密钥KA加密的报文,这个报文包含A与TGS通信的会话密钥Ks,以及AS要发送给TGS的票据(这个票据是用TGS的对称密钥KTG加密的,A无法读取)
- A本身并不保存密钥KA,但当这个报文到达A时,需要用户输入其身份口令(通常是登录密码),主机A会使用该口令和适当的算法一起生成密钥KA,然后使用密钥KA解密AS发送过来的报文,提取出报文内容(即上述提到的密钥Ks和AS给TGS的票据),随后,主机A会在内存中销毁口令和KA,来避免长期持有KA带来的风险
- A向TGS发送以下内容:
- 鉴别服务器AS发来的票据,由于只有A能通过密钥KA解密出该票据(虽然A看不到其中内容),因此TGS可以信任A而不需要鉴别
- 服务器B的信息,表明A请求B的服务
- 用Ks加密的时间戳T,它用来防止入侵者的重放攻击
- TGS向A和B分别发送两个票据,其中都包含A和B通信的会话密钥KAB。给A的票据用Ks加密,给B的票据用B的密钥KB加密
- A向B转发TGS发来的票据,同时发送用KAB加密的时间戳T
- B把解密的时间戳T加1,然后用KAB加密回送给A,来证实收到了票据
- 之后A和B就使用TGS给的会话密钥KAB进行通信
- TGS发出的票据都设置较短的有效期,超过有效期的票据作废。Kerberos要求所有使用Kerberos的主机必须在时钟上进行“松散的”同步,即要求所有主机的时钟误差不能太大,以防止重放攻击
公钥的分配
公私钥通信模型可能会受到中间人攻击,如:假设A想与B通信并发起了请求,但请求被C截获了,于是C开始冒充A向B发起连接请求。在A与B交换公钥时,C可以截获它们并修改为自己的公钥,之后A和B发送的数据都会使用C的公钥加密,C可以任意使用自己的私钥解密,纂改报文,并用A/B的公钥加密后发送给对应主机,以至于AB双方都意识不到C的存在。
解决的办法就是A需要确认自己拿到的公钥确实是B的(B同理可以确认公钥确实是A的),这一将公钥与特定实体绑定的工作由认证中心CA(Certification Authority)来做。CA会给已经经过验证的实体发放证书(certificate),证书包含公钥和公钥持有者的标识信息(人名或IP地址),且CA会对证书进行数字签名。不同服务使用的证书不同(如:TLS证书,安全电子邮件证书),证书可能包含以下内容:
- 证书版本号
- 证书序列号,即证书的唯一标识
- CA对该证书进行签名的算法
- 颁发者的名称,即CA的标识
- 证书有效期,包含证书合法性开始时间和结束时间
- 持有该证书的实体的标识
- 公钥以及该公钥使用的公钥算法
网络层安全IPsec
跨越多个地理区域的大型机构常常希望有自己的IP网络,并且希望机构内的路由器等大部分基础设施拥有底层的安全通信机制,而不需要依赖于运输层和应用层的安全机制。因此,企业的VPN网络广泛使用IPseci协议簇来保障数据传输的机密性,并提供完整性和真实性
IPsec(IP security的缩写)是一套能够在IP层提供互联网通信安全的协议簇,它本质上是一个框架,允许通信双方自由选择合适的算法和参数,而没有限定用户必须使用何种特定的加密和鉴别算法,但为保证互操作性,IPsec包含了一套加密算法,所有IPsec的实现都必须使用。IPsec协议簇中的协议可划分为以下三个部分:
- IP安全数据报格式的两个协议:鉴别首部 AH协议(Authentication Header)协议和封装安全有效载荷ESP协议(Encapsulation Security Payload)
- 有关加密算法的三个协议(不作讨论)
- 互联网密钥交换IKE协议(Internet Key Exchange)
IPsec的工作模式
当某源IPsec 实体(通常是一台主机或路由器)向一个目的实体(通常也是一台主机或路由器)发送安全数据报时,它可以使用AH协议或ESP协议来完成:
- AH协议提供源鉴别和数据完整性服务,但不提供加密服务
- ESP协议提供了源鉴别、数据完整性和加密服务,由于可以加密,因此ESP协议的使用比AH协议要广泛得多
IPsec支持IPv4和IPv6,IPv6中,AH和ESP都是扩展首部的一部分。由于ESP协议使用更为广泛,因此主要介绍ESP协议。使用ESP或AH协议的IP数据报称为IP安全数据报(或IPsec数据报),IP安全数据报有以下两种不同的工作方式:
- 运输方式(transport mode):在运输层报文段的前后分别添加若干控制信息,再加上IP首部,构成IP安全数据报。
- 隧道方式(tunnel mode):在IP数据报的前后分别添加若干控制信息,再加上新的IP首部,构成一个IP安全数据报
无论使用哪种方式,最终的IP安全数据报的IP首部都是不加密的,方便路由器识别和路由,加密的只有数据报的数据部分,这也称为有效载荷(payload)。由于目前使用最多的就是隧道方式,因此以下信息只限于隧道方式。
安全关联
在发送IP安全数据报之前,需要在源实体和目的实体之间创建一条网络层的逻辑连接,这个连接称为安全关联SA(Security Association)。SA是从源点到终点的单向连接,如要进行双向安全通信,则需要两个SA。
假定某公司有一个公司总部和一个在外地的分公司。总部需要和这个分公司以及在各地出差的n个员工进行双向安全通信。在这种情况下,一共需要创建(2+2n)条安全关联SA,在这些安全关联SA上传送的就是IP安全数据报。

当公司总部的主机要发送IP数据报给分公司的主机,必须先经过公司总部的路由器R1。然后经IPsec的加密处理后,成为IP安全数据报,IP安全数据报经互联网传输,到达分公司的路由器R2。路由器R2对IP安全数据报解密,还原出原始的数据报,发送给终点主机。但如果主机要访问的是公共互联网,不是分公司设备或外地员工的设备,则不会建立安全关联,而是作为普通IP数据报转发。
建立安全关联SA的路由器或主机,必须维护这条SA的状态信息,其状态信息包括:
- 一个32位的连接标识符,称为安全参数索引SPI(Security Parameter Index)
- 安全关联SA的源点和终点的IP地址(即路由器R1和R2的IP地址)
- 所使用的加密类型(例如,DES或AES)
- 加密的密钥
- 完整性检查的类型(例如,使用报文摘要MD5或SHA-1的报文鉴别码MAC)
- 鉴别使用的密钥
当路由器要通过SA发送IP安全数据报时,就必须读取SA的这些状态信息,以便知道如何把IP数据报进行加密和鉴别
IPsec数据报格式
以下是隧道工作方式下的IPsec数据报格式

数据报会通过以下步骤打包:
- 在原始IPv4数据报后面添加ESP尾部。ESP尾部有三个字段:
- 第一个字段是填充字段,用全0填充
- 第二个字段是填充长度(8位),指出填充字段的字节数,填充长度(8位)的最大值是255
- 最后一个字段是“下一个首部”(8位),这个字段的值指明,在接收端,ESP的有效载荷应交给什么样的协议来处理。由于IPsec数据报会有多个首部(如图),因此隧道方式下,ESP尾部中的“下一个首部”指的是ESP的有效载荷中的“原始的IP首部”,值为4。运输方式下,则“ESP的有效载荷”就应当是TCP或UDP报文段,值为协议对应值。
- 使用SA指明的加密算法和密钥,加密上述结果
- 在加密数据的前面添加ESP首部。ESP首部有两个32位字段。
- 第一个字段存放安全参数索引 SPI,通过同一个SA的所有IP安全数据报都使用同样的SPI值
- 第二个字段是序号,用来防止重放攻击和鉴别。请注意,当分组重传时序号并不重复。
- 按照SA指明的算法和密钥,对“ESP首部+加密的部分”生成报文鉴别码MAC。
- 把所生成的报文鉴别码MAC添加在ESP尾部的后面,和ESP首部、ESP的有效载荷、ESP尾部一起,构成IP安全数据报的有效载荷。
- 生成新的IP首部,通常为20字节长,和普通的IP数据报的首部的格式是一样的。需要注意的是,首部中的协议字段的值是50,表明在接收端,首部后面的有效载荷应交给ESP协议来处理。注意,“原始的IP首部”中,是用源主机和目的主机的IP地址分别作为源地址和目的地址,而在IP安全数据报的“新的IP首部”中,是使用路由器R1和R2(或出差员工的设备IP)的IP地址分别作为源地址和目的地址。
当分公司的路由器R2收到IP安全数据报后,先检查首部中的目的地址。发现目的地址就是R2,于是路由器R2就继续处理这个IP安全数据报。路由器R2找到IP首部的协议字段值(现在是50),就把IP首部后面的所有字段(即IP安全数据报的有效载荷)都用ESP协议进行处理。先检查ESP首部中的安全参数索引SPI,以确定收到的数据报属于哪一个安全关联SA(因为路由器R2可能有多个安全关联)。路由器R2接着计算报文鉴别码MAC,看是否和ESP尾部后面添加的报文鉴别码 MAC相符。如是,即知收到的数据报的确是来自路由器R1。再检验ESP首部中的序号,以证实有无被入侵者重放。接着要用和这个安全关联 SA对应的加密算法和密钥,对已加密的部分进行解密。再根据 ESP 尾部中的填充长度,去除发送端填充的所有0,还原出加密前的ESP有效载荷,即原始IP数据报,最后按照IP层转发逻辑转发。
IPsec的其他构件
- 安全关联数据库SAD(Security Association Database):用于存放各安全关联SA的相关数据,主机发送和接收IP安全数据报时,都在要在SAD中查找相应的SA
- 安全策略数据库SPD(Security Policy Database):主机所发送的数据报并非都必须进行加密,很多信息使用普通数据报用明文发送即可,SPD用于指明哪些数据报需要进行IPsec处理(这取决于源地址、源端口、目的地址、目的端口,以及协议的类型等信息)
- 互联网密钥交换IKE协议(Internet Key Exchange):一个VPN网络可能有上千个路由器和主机,且它们位置分散,人工键入SAD几乎不现实,因此IKE的作用就是为IP安全数据报创建安全关联SA,并自动生成SAD。IKEv2是其新的版本,它以另外三个协议为基础:
- Oakley:密钥生成协议
- 安全密钥交换机制 SKEME (Secure Key Exchange Mechanism):用于密钥交换。它利用公钥加密来实现密钥交换协议中的实体鉴别
- 互联网安全关联和密钥管理协议 ISAKMP (Internet Secure Association and KeyManagement Protocol):用于实现IKE中义的密钥交换,使IKE的交换能够以标准化、格式化的报文创建安全关联SA
运输层安全SSL与TLS
运输层有两个广泛使用的安全协议:
- 安全套接字层 SSL(Secure Socket Layer):由Netscape公司在1994年开发的安全协议,用于在TCP之上建立起一个安全通道,为通过TCP传输的应用层数据提供安全保障,曾被广泛用于基于万维网的各种网络应用
- 运输层安全 TLS(Transport Layer Security):1995年Netscape公司把SSL转交给IETF,希望能够把SSL进行标准化,于是IETF在SSL3.0的基础上设计出了TLS协议,为所有基于TCP的网络应用提供安全数据传输服务,是目前主流使用的运输层安全协议
- 安全电子交易SET(Secure Electronic Transaction)协议:专门为信用卡交易设计的协议,由Visa和MasterCard公司设计,由于SET交易中客户端要使用专门的软件(叫做浏览器钱包),同时商家要支付的费用比使用SSL 更加昂贵,因此SET在市场竞争中失败了
TLS
运输层安全(Transport Layer Security,TLS):它是对TCP的加强,提供了关键的进程到进程的安全性服务,包括加密、数据完整性和端点鉴别。TLS不是与TCP和UDP 在相同层次上的第三种因特网运输协议,而是一种对TCP的加强,这种强化是在应用层上实现的。
TLS有它自己的套接字API,类似于传统的TCP套接字API。当一个应用使用TLS时,发送进程向TLS套接字传递明文数据,发送主机中的TLS则加密该数据,并将加密的数据传递给TCP 套接字。加密的数据经因特网传送到接收进程中的TCP套接字。该接收套接字将加密数据传递给TLS套接字,由其进行解密,最后将明文数据传递给接收进程。

TLS提供的安全服务可归纳为以下三种:
- 服务器鉴别:允许用户证实服务器的身份。客户端通过验证来自服务器的证书,来鉴别服务器的真实身份并获得服务器的公钥
- 客户鉴别:TLS可选的安全服务,允许服务器证实客户的身份。
- 加密的会话:对客户和服务器间发送的所有报文进行加密,并检测报文是否被篡改。
TLS记录
在传输过程中,TLS为了确保数据不被篡改,会对数据进行完整性鉴别。对于TLS而言,应用层交付的数据一段连续的字节流,如果TLS将应用层交付的数据视为一份完整数据(即整个TCP连接传输的数据)进行完整性校验,那么它可能需要等到连接结束后,才能对所有数据进行完整性验证,这显然不现实。因此,TLS将数据流分割为了记录,TLS会将记录与会话鉴别密钥放入一个散列函数中生成报文鉴别码MAC,然后使用会话密钥加密记录+MAC并加上一些信息字段生成TLS记录,交付TCP套接字,TLS记录的结构类似于:

- 类型字段:占用1字节,指出了该记录是握手报文还是包含应用数据的报文,它也用于关闭TLS连接
- 版本字段:占用2字节,指出TLS的版本,通常为1.2或1.3
- 长度字段:占用2字节,指出该字段之后数据+鉴别码的长度,接收端依据该字段从连续TCP字节流中截断出TLS记录,以解决TCP字节流无报文边界的问题
- 载荷部分:TLS1.2内容为数据+报文鉴别码MAC+填充,TLS 1.3通常是数据+ AEAD认证Tag。虽然长度字段支持最大值64KB,但协议规定明文数据部分最大长度为16KB,因此加上鉴别部分达不到最大限制值
记录的序号
TLS 1.0/1.1/1.2中,为了防止TLS记录被重放、删除、插入、重排序,客户端和服务端会为每个传输方向都会维护一个64位的TLS记录序号:
- 序号从0开始,每发送一条TLS记录,序号+1
- 序号由双方在本地维护,不插入TLS记录字段中,不在网络上传播,双方隐式同步,减少暴露的信息
- 进行报文完整性鉴别时,双方会将序号作为计算MAC时的输入之一,来确认这一条记录在整个TLS记录流中的位置是否正确
TLS 1.3使用AEAD,对称加密算法本身就自带了完整性鉴别功能,不再直接使用序号,而是会在AEAD中隐式维护记录序号。
TLS握手
TLS握手(TLS Handshake)的核心任务是:协商加密算法、验证服务器身份,并安全地生成双方后续通信所使用的对称加密密钥。TLS会同时使用对称加密和非对称加密:握手阶段使用非对称密码学协商密钥,正式通信阶段则使用对称加密传输数据。
TLS 1.2握手流程
- 客户端发送ClientHello报文,其中包含客户端支持的TLS版本、支持的密码套件(Cipher Suite)、客户端随机数 client_random(防重放攻击)、支持的扩展功能(如SNI、ALPN等)
- 服务器收到后回复ServerHello报文,内容包括最终采用的TLS版本、选定的密码套件(cipher suite)、服务端随机数 server_random,其中密码套件用于同时描述身份认证算法、密钥交换算法、对称加密算法、报文完整性鉴别算法,如:TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,RSA表示使用RSA证书进行身份认证,ECDHE表示使用椭圆曲线Diffie-Hellman临时密钥交换,AES_128_GCM 表示后续通信采用AES-GCM对称加密,SHA256作为相关哈希算法参与密钥派生与握手校验
- 同时,服务器还会发送数字证书(Certificate),其中包含服务器公钥以及由CA签名的身份信息。客户端会根据认证机构CA公开发布的RSA/ECDSA公钥和证书链验证该证书是否合法,包括:CA签名是否可信、域名是否匹配、是否过期、是否被吊销
- 上述流程中信息传输是明文的,验证通过后,双方开始协商会话密钥:
- 传统RSA密钥交换:客户端生成48字节预主密钥pre_master_secret,然后用服务器证书里的RSA公钥加密该 pre_master_secret并发送给服务器,它只能用服务器的私钥解密(这也是RSA模式缺乏前向安全性的根源,一旦未来服务器私钥泄露,且攻击者记录了历史TLS流量,历史会话也会被解密)。至此,服务器与客户端同时拥有了client_random、server_random、pre_master_secret,双方用相同的伪随机函数PRF生成主密钥master_secret。接着再用 master_secret 和两个随机数通过 PRF 展开出最终需要的密钥材料块(key block),然后按需要截取出以下密钥:
- 客户端写入密钥 (Client Write Key):用于客户端向服务器发送数据时的对称加密
- 服务端写入密钥 (Server Write Key):用于服务器向客户端发送数据时的对称加密
- 客户端MAC密钥(Client Write MAC Key):用于客户端发送数据时生成报文鉴别码(MAC)
- 服务端MAC密钥(Server Write MAC Key):用于服务器发送数据时生成报文鉴别码(MAC)
- 如果需要,还可以继续截取出客户端初始向量(IV)和服务端初始向量(IV),其作用参考上文“分组加密思想-CBC密码块链接”
- 至此,通信的两端都有两套用于双向通信用的对称密钥和报文鉴别密钥,两个通信方向使用两套不同的密钥
- 现代TLS通常使用ECDHE(Elliptic Curve Diffie-Hellman Ephemeral,椭圆曲线临时 Diffie-Hellman)进行密钥交换,它具备前向安全性(Forward Secrecy),其流程为:服务器生成一对临时的椭圆曲线公私钥对,然后将公钥放入Server Key Exchange报文中发送给客户端(明文传输,但为了防止中间人伪造并替换该临时公钥,服务器会用私钥对报文内容进行签名),客户端也生成一对临时的椭圆曲线公私钥对,将其公钥通过Client Key Exchange报文发给服务器(TLS握手主要认证服务端身份,并确保服务端公钥不会被替换,客户端身份无关紧要,因此客户端的公钥会被明文传输时不签名。只有在双向TLS中(mTLS),客户端有证书和私钥时,Client Key Exchange报文才会被签名)。之后,客户端用自己的临时私钥+服务器的临时公钥计算得出pre_master_secret,服务器用自己的临时私钥+客户端的临时公钥计算出完全相同的预主密钥pre_master_secret。之后的过程与RSA类似,通过client_random、server_random、pre_master_secret计算出分别用于通信和报文鉴别的密钥
- 传统RSA密钥交换:客户端生成48字节预主密钥pre_master_secret,然后用服务器证书里的RSA公钥加密该 pre_master_secret并发送给服务器,它只能用服务器的私钥解密(这也是RSA模式缺乏前向安全性的根源,一旦未来服务器私钥泄露,且攻击者记录了历史TLS流量,历史会话也会被解密)。至此,服务器与客户端同时拥有了client_random、server_random、pre_master_secret,双方用相同的伪随机函数PRF生成主密钥master_secret。接着再用 master_secret 和两个随机数通过 PRF 展开出最终需要的密钥材料块(key block),然后按需要截取出以下密钥:
- 计算出会话密钥后双方会分别发送ChangeCipherSpec报文,表示后续发送的TLS记录将开始使用协商好的对称密钥和加密参数进行保护。随后双方会发送Finished 报文验证此前握手过程是否被篡改。至此TLS握手完成,后续应用层数据(如HTTP数据)都会被加密传输和完整性鉴别
TLS 1.2的特点
- TLS 1.2的完整首次握手通常需要2个RTT后,应用层数据才能开始加密传输,握手延迟较高
- 使用多次握手报文完成版本协商、密码套件协商、证书认证、密钥交换以及会话密钥生成等过程
- 传统 RSA 密钥交换模式不具备前向安全性,因此现代 TLS 1.2 通常采用 ECDHE 临时密钥交换
- 握手过程中,大部分握手报文以明文形式传输,仅通过证书签名和 Finished 阶段保证完整性与身份认证
- 密钥派生流程较复杂,需要经历 pre_master_secret、master_secret、key_block 等多个阶段
- 密码套件设计较为庞杂,同时需要协商密钥交换、认证、加密、MAC 等多种算法组合
TLS 1.3握手流程
TLS 1.3对握手流程进行了大幅简化,移除了大量历史兼容设计,强制使用具备前向安全性的ECDHE密钥交换,并将首次握手优化为 1-RTT。其主要流程如下:
- 客户端发送ClientHello报文,其中包含客户端支持的TLS版本、密码套件、客户端随机数 client_random,并直接附带客户端的ECDHE临时公钥(Key Share)
- 服务器收到后回复ServerHello报文,确定最终采用的TLS版本、密码套件、服务端随机数 server_random,同时返回服务端的ECDHE临时公钥,TLS1.3的密码套件仅描述AEAD算法(同时提供对称加密和完整性鉴别)、哈希算法,不包含密钥交换
- 客户端用自己的临时私钥+服务器的临时公钥计算得出pre_master_secret,服务器用自己的临时私钥+客户端的临时公钥计算出完全相同的预主密钥pre_master_secret,之后会使用HKDF(基于 HMAC 的密钥派生函数)逐步生成多个阶段性的密钥,TLS会在握手、数据传输阶段使用不同密钥,以实现密钥隔离:
- 双方会根据预主密钥生成 Handshake Secret,随后从中进一步派生出Client/Server Handshake Traffic Secret,然后由此生成:
- 握手阶段的数据加密密钥(Handshake Key)
- 初始化向量 IV
- Finished 报文使用的鉴别密钥
- 双方会根据预主密钥生成 Handshake Secret,随后从中进一步派生出Client/Server Handshake Traffic Secret,然后由此生成:
- 从这里开始,后续的握手流程会使用握手密钥加密
- 服务器发送EncryptedExtensions报文,其中包含 ALPN、SNI 响应等扩展信息
- 服务器发送数字证书(Certificate),向客户端证明自身身份。之后服务器发送 CertificateVerify 报文,使用证书对应私钥对之前的握手消息摘要进行数字签名,从而证明服务器确实拥有该证书对应的私钥,而不是仅仅转发了一张伪造或窃取的证书
- 最后服务器发送Finished 报文,其中包含基于握手密钥计算出的 MAC(消息鉴别码),用于证明此前握手消息未被篡改,同时验证双方确实持有相同的共享密钥。客户端验证通过后,也会向服务器发送自己的 Finished 报文。至此 TLS1.3 握手完成
- 双方验证完 Finished 报文、确认握手未被篡改后,会通过预主密钥pre_master_secret派生出最终的Client/Server Application Traffic Secret,并继续生成真正用于应用数据传输的:会话加密密钥(Application Key)、对应IV
TLS 1.3的特点
- 由于强制规定使用ECDHE密钥交换而不需要协商,由此客户端可以在ClientHello中提前发送ECDHE公钥,因此 TLS 1.3首次完整握手通常只需要1个RTT即可建立加密通信;若客户端拥有此前会话恢复得到的PSK(Pre-Shared Key),还可以进一步使用 0-RTT 提前发送部分应用数据,从而继续降低延迟
- 服务器证书等主要握手流程以加密形式传输,减少信息泄露
- 使用分层密钥派生结构,它有以下优势:
- 不同阶段使用不同密钥,握手密钥与应用数据密钥彼此隔离,避免一个阶段密钥泄露影响全部通信
- 支持 Key Update,通信过程中还能重新派生新的应用密钥
- 所有密钥都依赖ECDHE临时密钥交换,因此天然具备前向保密性(Forward Secrecy)
TLS关闭连接
如果要终止TLS会话,一个简单的方法是直接终止底层的 TCP连接来结束该TLS会话,即直接发送一个TCP FIN报文段。但这有一个隐患,中间人可以冒充任意一方身份发送TCP FIN报文段来发起截断攻击(truncation altack),强行中断双方的通信。
为此,TLS正确关闭连接的方法是:在类型字段中指出该记录是否是用于终止该TLS会话的。虽然TLS类型是以明文形式发送的,但在接收方会使用记录的MAC对它进行鉴别,因此中间人伪造并发送一个关闭连接的TLS记录是无效的,同时,如果通信双方在收到一个关闭TLS记录之前突然收到了一个TCP FIN,说明TCP连接被异常关闭了(链路故障、TCP截断攻击),这将被作为异常处理。
TLS 1.2和1.3的密码学套件
TLS 1.2 和 TLS 1.3 在密码学套件(Cipher Suites)的设计上有很大的不同。TLS 1.2 采用传统的“大杂烩”组合方式,支持的密码学套件很多,而 TLS 1.3 进行了大刀阔斧的精简,废除了所有不安全的算法,强制要求密钥交换使用具有有向前保密能力的ECDHE/DHE,将密钥交换和身份认证与对称加密和完整性校验彻底解耦
身份认证算法
- 1.2:RSA(最常用),ECDSA(椭圆曲线数字签名算法),PSK(预共享密钥,常用于嵌入式/IoT),SRP(安全远程密码)
- 1.3:RSA(仅支持更安全的PSS填充模式,即RSA-PSS),ECDSA,EdDSA(Ed25519和Ed448,新型Edwards曲线签名,更高效安全),PSK(用于恢复会话或预共享密钥场景)
密钥交换算法 - 1.2:RSA(不提供前向安全性,已被现代安全规范弃用),ECDHE(短暂椭圆曲线迪菲-赫尔曼,提供前向安全性,主流),DHE(短暂迪菲-赫尔曼,提供前向安全性),ECDH / DH(静态的迪菲-赫尔曼,极少使用),PSK / DHE-PSK / ECDHE-PSK
- TLS 1.3 的密钥交换通过 Key Share 扩展独立协商,不再由密码套件决定,主要使用ECDHE(主要基于命名曲线:X25519、Secp256r1、Secp384v1)、DHE(基于有限域的 Diffie-Hellman,通常需要至少 2048 位密钥)
对称加密算法 - 1.2:AES-GCM(如 AES-128-GCM, AES-256-GCM,主流且高效),AES-CBC(如 AES-128-CBC, AES-256-CBC,容易受到隐蔽通道攻击),CHACHA20-POLY1305(优秀的流加密算法,常用于移动端)
- 1.3:只支持 AEAD(关联数据认证加密)模式,加密和完整性鉴别融为一体,AES-GCM(AES-128-GCM, AES-256-GCM),CHACHA20-POLY1305,AES-CCM(AES-128-CCM, AES-128-CCM-8,常用于物联网等轻量级场景)
报文完整性鉴别算法 - 1.2:对于 AEAD 模式(如 GCM、CHACHA20-POLY1305):完整性校验已内置在对称加密算法中,对于CBC模式(需要配合 HMAC)常用SHA-256、SHA-384
- 1.3:由于 TLS 1.3 强制使用 AEAD,其对称加密算法本身就自带了完整性鉴别功能(如 GCM 和 POLY1305 提取的 Tag),套件尾部的 Hash 算法(如 SHA-256、SHA-384)在 TLS 1.3 中主要用于 HKDF(密钥衍生函数) 和握手消息的哈希校验,不再作为独立的 HMAC 算法去拼装 CBC 模式
电子邮件安全协议PGP
PGP(Pretty Good Privacy)是一种用于电子邮件安全的经典加密方案,它综合使用了对称加密、非对称加密、数字签名和哈希等密码学技术,以同时实现邮件内容的保密性、完整性、发送者身份认证以及不可否认性。
PGP工作流程
假设A通过PGP加密像B发送明文邮件X,它的大致工作流程如下:
- A有三个密钥:自己的私钥、B的公钥和自己生成的一次性密钥。B有两个密钥:自己的私钥和A的公钥
- A对明文邮件X进行MD5运算,得出MD5报文摘要H
- 用A的私钥对H进行加密,作为报文鉴别码MAC,把它拼接在明文X后面,得到扩展的邮件(X,MAC).
- 使用A自己生成的一次性密钥对扩展的邮件(X,MAC)进行加密
- 用B的公钥对A生成的一次性密钥进行加密
- 把加密后的一次性密钥和加密后的扩展邮件发送给B
- B接收后,用私钥解密出一次性密钥
- 用一次性密钥解密出邮件
- 用A的公钥解密H,得到邮件的MD5摘要
- 对解密出的报文也进行一次MD5运算,来检查是否被篡改
- 双方公钥可以通过第三方分享,在给邮箱地址的同时附带公钥等形式分发
虽然PGP在技术设计上非常经典,并且真正实现了端到端加密,但由于其密钥管理复杂、公钥分发困难、用户体验较差等问题,它并未成为大众互联网邮件系统的主流方案。目前互联网电子邮件安全更广泛采用的是基于TLS的传输层加密机制,例如SMTP over TLS、STARTTLS、IMAPS、POP3S等。这类方案通过TLS对邮件在客户端与服务器、服务器与服务器之间的传输链路进行加密,从而防止邮件在传输过程中被窃听。
运行安全
在计算机网络中,仅仅依靠加密和认证协议来保护数据本身是不够的,通常还需要在系统的边界和内部执行一定防御措施。这些措施通常依赖系统安全中的两个核心组件:防火墙与入侵检测系统。它们分别扮演着“门卫”和“巡逻哨兵”的角色
防火墙
防火墙(firewall)是一种特殊的编程路由器,安装在内部网络与外部互联网之间,用于实施访问控制策略。它的核心任务就是“阻止”和“允许”:阻止非必要的、有风险的通信流量进出内部网络,同时允许合法的通信畅通无阻。从技术实现上看,防火墙主要分为两类:
- 分组过滤路由器:根据预设的过滤规则,检查每个进出分组的网络层和运输层等首部信息(如源/目的IP地址、端口号等),然后决定是转发还是丢弃该分组,是最为常见和基础的防火墙
- 应用网关(也称为代理服务器):这是一种更强大也更复杂的防火墙。它在应用层扮演报文中继的角色。所有进出网络的应用程序报文都必须通过它。应用网关不仅可以检查数据包头部,还能深入分析应用层数据的内容,并实现高层的用户鉴别。比如,一个邮件网关可以检查每封外发邮件的正文,看看是否包含敏感词,从而决定是否放行
入侵检测系统
入侵检测系统IDS(Intrusion Detection System)通过对进入网络的分组进行深度分析与检测发现疑似入侵行为的网络活动,并进行报警或执行预设的阻断操作,尽可能减少入侵造成的损失,其核心检测方法有两种:
- 基于特征的检测:这种方法依赖于一个不断更新的“攻击特征库”。入侵检测系统会持续监测网络流量,一旦发现有分组或分组序列与库中的已知攻击特征(如特定代码串)相匹配,就判定为入侵行为。该方法对已知威胁非常有效,但无法识别新的、未知的攻击
- 基于异常的检测:这种方法更智能化。它会先观察并学习网络在正常运行状态下的流量统计特性和规律,形成一个“正常轮廓”。当监测到网络流量的某种统计规律(如流量大小、连接频率)严重偏离正常轮廓时,就会认为可能发生了入侵。它能发现未知威胁,但误报率可能较高