Archipelago

Lec 23安全通道

讲义完成更新于 2026-08-27

摘要

给定一个结合了加密、MAC(消息认证码)和签名的协议,判断它是否提供了机密性(confidentiality) 和/或 完整性(integrity),以及它是否能够抵御重放攻击和反射攻击。 你不需要理解加密/解密、MAC 或签名/验证背后的数学原理。我们只会问你关于将这些函数作为构建模块的方案。你应该理解它们提供的属性以及它们如何在安全通道中正确使用,但不需…

Lec 23 安全通道

阅读参考书 §11.3-11.5

思考题

  • 给定一个结合了加密、MAC(消息认证码)和签名的协议,判断它是否提供了机密性(confidentiality) 和/或 完整性(integrity),以及它是否能够抵御重放攻击和反射攻击。
    • 你不需要理解加密/解密、MAC 或签名/验证背后的数学原理。我们只会问你关于将这些函数作为构建模块的方案。你应该理解它们提供的属性以及它们如何在安全通道中正确使用,但不需要理解,例如,加密提供机密性但不提供完整性的数学原因。
  • 给定 p 和 g,在两方之间执行 Diffie-Hellman 密钥交换
  • 解释对 Diffie-Hellman 密钥交换的攻击
  • 解释如何用公钥密码学来验证用户身份,包括证书的创建和分发方式
  • 你不需要理解 TLS 握手细节,尽管你应该能够识别其中的熟悉元素(序列号、密钥等)

引入

到目前为止,我们已经处理了对手尝试在服务器上访问数据的问题。现在我们的对手开始从外部,即从网络中观察数据。

有些数据包的有效载荷可能会反映出你正在干嘛, 即使你看不懂 Header 信息。有时,流量很容易与 个人 联系起来,无论是在数据包头还是数据包数据中.

image-20250909143621857

今天我们将重点讨论如何保护 数据包数据免受攻击者攻击

  • 下一节,我们将讨论如何保护元信息(例如数据包头)免受攻击者攻击

策略:提供机密性(攻击者无法获知消息内容)和完整性 (攻击者无法篡改数据包而不被发现)。

威胁模型: 攻击者可以观察网络数据、篡改数据包并插入自己的数据包。

encrypt(key, message) -> 密文
decrypt(key, 密文) -> message
/*
encrypt(34fbcbd1, "hello, world") = 0x47348f63a679 
26cd393d4b93c58f78c 
decrypt(34fbcbd1, "0x47348f63a67926cd393d4b93c58f7 
8c") = hello, world
*/

性质:给定密文(ciphertext),几乎不可能在不知道 key 的情况下获取 message。

image-20250909144158679

攻击者无法确定消息,但可能 能够巧妙地修改密文,以便将其解密为 不同的消息

认证消息

区别于机密性

基于 Key 的认证模型

签名和认证的性质

Key 分布

消息机密性

安全协议

在前面的章节中,我们发现在远程服务进行身份验证(authenticating)时,需要保护主体的密码,同时也需要安全地分发密钥等。安全协议可以实现这些目标。安全协议是一种消息交换过程,旨在让相互不信任的各方达成某个目标。在涉及两方的安全协议中,通常采用"来回交换"模式(back-and-forth pattern)。某些安全协议涉及两个以上的参与方,这种情况下,协议的模式可能会更加复杂。例如,密钥分发通常至少需要三个参与方(两个主体和一个受信任的第三方)。

标准的网络协议通常假设通信双方是合作的,并且彼此信任。然而,在设计安全协议时,我们假设协议中的某些参与方可能是对手(adversaries)。

用例:密钥分发问题

为了说明安全协议的必要性,我们研究两个用于密钥分发的协议。我们已经看到,密钥分发基于名称发现协议(name discovery protocol),而该协议始于受信任的物理交付。因此,我们假设 Alice 曾与 Charles 线下见过面,Charles 也曾与 Bob 线下见过面。那么,问题来了:是否存在这样一个协议,使得 Alice 和 Bob (他们从未见过面)能够在不受信任的网络上安全地交换密钥?

公钥方案相对更简单。假设 Alice 和 Bob 都已经知道 Charles 的公钥(因为他们分别见过),Charles 都知道 Alice 和 Bob 各自的公钥。如果这两者都信任 Charles,那么可以通过 Charles 来交换密钥。具体协议流程:

  1. Alice 向 Charles 发送请求(不需要加密或签名):Alice →\rightarrow Charles: {"请给我 Bob 的密钥"}

他无法确认消息是否真的来自 Alice,因为网络协议的源地址目标地址不经过身份认证

  1. Charles 回复 Alice: Charles →\rightarrow Alice: {"要与 Bob 通信,请使用公钥KBpubK_{Bpub}"}Cpriv_{Cpriv}

这里,{M}k\{M\}_k记号表示使用密钥 k 对消息 M 进行签名。这个例子中,消息使用了 Charles 的私钥(Cpriv)进行签名,消息中包含了 Bob 的公钥 Bpub。当 Alice 收到这条消息后,她可以通过 Charles 的公钥(Cpub)进行验证。如果验证成功,则说明这条消息确实来自 Charles,不会被篡改。

为了说明缺乏明确性(explicit)可能带来的问题,假设前面提到的消息 2 编程以下版本

  1. Charles 回复 Alice: Charles →\rightarrow Alice: {"请使用公钥KBpubK_{Bpub}"}Cpriv_{Cpriv}

Alice 无法确定 KBpub 是谁的公钥,这时,一个恶意的对手 Lucifer(曾与 Charles 见过面,但是不知道 Lucifer 是恶意的)可以利用这点发动攻击。攻击方式如下:

  1. Lucifer 向 Charles 请求自己的公钥:Lucifer →\rightarrow​ Charles: {"请给我 Lucifer 的密钥"}
  2. Charles 回复 Lucifer: Charles →\rightarrow Lucifer: {"请使用公钥KLpubK_{Lpub}"}Cpriv_{Cpriv}​
  3. Alice 请求 Bob 公钥: Alice →\rightarrow Charles: {"请给我 Bob 的密钥"}

这时,Lucifer 拦截 Charles 的回复,并用之前存下的回复替换掉它,然后转发给 Alice

  1. (伪造) →\rightarrow Alice: {"请使用公钥KLpubK_{Lpub}"}Cpriv_{Cpriv}

Charles 的公钥可以验证这条消息的签名,但 Alice 误以为 KLpub(Lucifer 的公钥)是 Bob 的公钥。Lucifer 如果能拦截 Alice 发送给 Bob 的消息,他就可以冒充 Bob。

如何防止这种攻击? 如同前面所说,保持明确性,要与 Bob 通信,请使用公钥 KBpub。

回到正确的协议,当 Alice 收到 Charles 的回复后,她可以使用自己的私钥签名任何想要发送给 Bob 的消息,并且使用 Bob 的公钥加密该消息;Bob 的回复也可以采用相同的方法,即 Bob 通过类似的方式从 Charles 那里获取 Alice 的公钥。

为什么 Bob 不能直接把公钥发给 Alice?

Bob 无法 通过不安全的信道直接发送自己的公钥给 Alice,即使他对公钥进行签名也不行。原因是:Alice 无法相信 一个由未知公钥签名的消息,即公钥自己证明自己的身份是不可信的。如果 Alice 收到 Charles 签名的消息(类似消息 2),她就可以相信该消息的真实性,前提是她信任 Charles 能够谨慎地进行公钥绑定。

Charles 作为证书颁发机构(CA),这样的消息(消息 2)被称为证书,它包含 Bob 的名字和公钥,证明 Bob 和该公钥之间的绑定关系。如果 Bob 事先从 Charles 那里获得了这份证书,他也可以直接把这份证书发送给 Alice,而不需要 Alice 额外向 Charles 询问 Bob 的公钥。在该协议中,Charles 的角色是证书颁发机构(Certificate Authority, CA),负责验证公钥的归属并提供可信的公钥分发服务。这种基于证书的公钥分发方法,后来发展为公钥基础设施(PKI),并被广泛应用于 SSL/TLS 证书、电子签名 等安全通信场景

设计安全协议

安全协议除了底层密码学转换所面临的攻击外,还容易受到几种攻击。

  • 已知密钥攻击,攻击者获取了之前使用的某个密钥,然后利用这些信息来确定新的密钥。
  • 重放攻击:攻击者记录了会话的一部分,并在稍后重新播放这些部分,希望接收方将重放的消息视为新消息
  • 冒充攻击:攻击者冒充协议中的其他参与方。这种攻击的一个常见版本是中间人攻击,攻击者在两个参与方之间中继消息,冒充每个参与方与对方通信,并在消息传递过程中读取它们。
  • 反射攻击:攻击者记录了会话的一部分,并将其重放给最初发送该消息的一方。使用共享密钥的协议有时容易受到这种特殊类型的重放攻击

认证协议

为了说明设计安全协议时遇到的问题,我们将介绍两个简单的认证协议。第二个协议使用了质询-响应机制

一个错误的密钥交换协议

质询-响应协议(challenge-response protocol)在 SSL/TLS 之上运行时,假设 SSL/TLS 能够建立一个机密且经过认证的通信信道,而这需要通信双方能够在不受信任的网络上安全地交换密钥。这种密钥交换是可行的,但必须谨慎处理。我们考虑两种不同的密钥交换协议。第一个协议是不正确的,而第二个(据目前所知)是正确的。这两个协议的目标相同,即让双方使用公钥系统协商一个共享密钥,该密钥可用于加密通信。

在第一个协议中,有三方参与:Alice、Bob 和证书授权机构(CA)。协议流程如下:

  1. Alice →\rightarrow CA: {"请给我 Alice 和 Bob 的证书"}
  2. CA →\rightarrow Alice:{"这里是是证书:", {Alice, Apub_{pub}, T}CApriv_{CApriv}, {Bob, Bpub_{pub}, T}CApriv_{CApriv}}

这个协议中,CA 返回了 Alice 和 Bob 的证书,这个证书将名称绑定到了各自的公钥,每个证书斗殴一个时间戳来判断证书是否是新鲜的,并且由 CA 签名。拿到 CA 提供的证书后,Alice 构造一个加密消息发送给 Bob:

  1. Alice →\rightarrow Bob: {"这是我的证书和一个提议的密钥: ", " {Alice, Apub_{pub}, T}CApriv_{CApriv}", {KAB_{AB}, T}Apriv_{Apriv}}Bpub^{Bpub}

该消息包含 Alice 的证书以及她提议的共享密钥(KABK_{AB})。Bob 可以使用 CA 的公钥验证 Apub 是否确实来自 Alice。共享密钥KABK_{AB}由 Alice 使用她的私钥签名,Bob 可以用ApubA_{pub}验证其真实性。该消息整体使用 Bob 公钥加密,因此只有 Bob 能够读取KABK_{AB},随后 Alice 用KABK_{AB}加密消息发送给 Bob:

  1. Alice ⇒ Bob:{"这是我的消息:", …… T}KAB^{K_{AB}}

这个协议存在什么问题?提示:注意 Alice 在消息 3 中只对部分内容进行了签名,而不是对整条消息签名。请记住,我们应该假设协议的某些参与方可能是攻击者。

这个协议存在潜在问题的原因应该是显而易见的,因为它违反了 显式设计原则(be explicit design principle)。协议的核心部分出现在消息 3 中,其中包含 Alice 提议的共享密钥:{KAB_{AB}, T}Apriv_{Apriv}, Alice 告诉 Bob,KAB 在时间 T 时是 Alice 和 Bob 之间的合适的密钥。但是缺少Alice 和 Bob 的名字。这意味着这段消息的解释取决于对话的上下文。因此,Bob 可以利用这部分消息伪装成 Alice。例如,Bob 可以向 Charles 发送一条消息,声称自己是 Alice,并提议使用 KAB 进行加密通信。

假设 Bob 想冒充 Alice 与 Charles 进行通信,他可以按照以下步骤操作:

  1. Bob →\rightarrow CA :{"请给我 Bob 和 Charles 的证书"}
  2. CA →\rightarrow Bob:{"这里是证书:", {Bob, Bpub,T′_{pub}, T'}CApriv_{CApriv},{Charles, Cpub_{pub}, T'}CApriv_{CApriv}}
  3. Bob →\rightarrow Charles:{"这是我的证书和一个提议的密钥: ", " {Alice, Apub_{pub}, T}CApriv_{CApriv}", {KAB_{AB}, T}Apriv_{Apriv}}Cpub^{Cpub}

Bob 精心构造了消息 3, 他在消息中放入了 Alice 的证书(这是他从与 Alice 交谈时获取的),而不是提议一个新的密钥,他直接插入了 Alice 签名的 KAB 提议。Charles 无法判断这条消息 3 并非来自 Alice。事实上,他会认为这条消息确实是 Alice 发送的,因为{KAB, T} 是用 Alice 的私钥签名的。因此,Charles 误以为他拥有了一个仅与 Alice 共享的密钥,但实际上 Bob 也掌握了 KAB

然后,Bob 可以向 Charles 发送消息:

  1. Bob ⇒ Charles:{"请把商业机密计划发给我。——你亲爱的 Alice"}KAB

这个攻击的一个 基本前提 是,攻击者(Bob)在某些方面是受信任的。因为 Alice 必须先与 Bob 进行通信,Bob 才能利用这次对话的结果冒充 Alice。这个问题的根源:缺乏显式性。这个案例表明,试图通过加密来实现身份认证是一个基本上错误的做法,因此现在这种方法已被认为是不安全的设计原则