Archipelago

Lec 1加密哈希函数与单向性

讲义完成更新于 2026-09-16
承接

这是当前课程已收录的第一篇。

Lec 1 加密哈希函数与单向性

关键词:随机预言机模型、单向性、抗碰撞性、生日攻击、性质间的蕴含关系

TL;DR

  • 随机预言机把每个新输入映射为独立均匀输出,是分析哈希协议的理想模型;现实中的 SHA-2/SHA-3 只是具体、公开的替代函数。
  • 单向性、抗碰撞与目标抗碰撞回答不同攻击问题,彼此不能随意替换;选择性质必须从上层协议真正需要阻止的攻击出发。
  • 对 dd 位输出,通用原像搜索约需 2d2^d 次查询,碰撞搜索受生日界限制约需 2d/22^{d/2} 次,因此碰撞安全位数约为输出长度的一半。

0. 一句话动机

我们需要一个把任意长度输入压缩成定长输出、且"看起来随机"的确定性公开函数,使得:知道输出几乎无法反推输入、且几乎不可能人为制造两个输入撞到同一输出。这一原语支撑了口令存储、文件完整性、数字签名与承诺等几乎所有上层协议。

h:{0,1}∗→{0,1}d.h : \{0,1\}^{*} \to \{0,1\}^{d}.

要求三点:确定性(deterministic)、公开(public,无密钥)、随机外观(random-looking)。

1. 随机预言机直觉

理想化的加密哈希被建模为一个随机预言机(random oracle, RO):

  • 对一个新的输入 xx,掷 dd 次硬币得到 dd 比特串作为 h(x)h(x),并把 (x,h(x))(x, h(x)) 记入一张表;
  • 之后再次收到同一 xx,先查表,命中则返回已记录的 h(x)h(x)(保证确定性)。

许多方案是在 RO 模型下被证明安全的。但现实中不存在真正的随机预言机,故实践中用**伪随机(pseudorandom)**的哈希函数(SHA-2/SHA-3 等)来近似。

🔎 直觉:RO 模型是一种"理想气体"假设——把哈希当成对每个新输入独立均匀采样的黑盒,便于证明上层协议安全;落地时再用具体函数替换,这一步替换在理论上有缺口(RO 不可实例化的反例存在),但工程上被广泛接受。

2. 期望性质

记号:{0,1}\{0,1\} 表示比特集合;negl(⋅)\mathrm{negl}(\cdot) 表示可忽略函数;y∈R{0,1}dy \in_R \{0,1\}^d​ 表示均匀随机取值。

定义

性质 1:单向性 / 抗原像 (One-Wayness / Preimage Resistance)

给定随机 y∈R{0,1}dy \in_R \{0,1\}^d,找到任意 xx 使 h(x)=yh(x) = y 在计算上不可行。

定义

性质 2: 抗碰撞 (Collision Resistance, CR)

找到两个不同输入 x≠x′x \ne x' 使 h(x)=h(x′)h(x) = h(x')​ 在计算上不可行。

定义

属性 3:目标抗碰撞 / 抗第二原像(Target Collision Resistance, TCR / 2nd-preimage) ::: 给定一个目标输入 xx,找到 x′≠xx' \ne x 使 h(x)=h(x′)h(x) = h(x') 在计算上不可行。

⚠️ 注意 CR 与 TCR 的差别:CR 中攻击者可自由选两个输入;TCR 中第一个输入 xx 是给定的,攻击者只能找第二个去撞它。前者显然更强。

3. 通用攻击

设输出长度为 nn 比特:

  • 求碰撞 ≈ 2n/22^{n/2}:来自生日攻击(birthday attack)——随机抽取约 2n/22^{n/2} 个输入,由生日悖论高概率出现碰撞。
  • 求逆(求原像)≈ O(2n)O(2^{n}):本质是穷举/暴力。

🔎 工程含义:这正是"抗碰撞所需输出长度要比抗原像翻倍"的原因。要抵御 21282^{128} 级别的碰撞攻击,输出至少要 n=256n = 256​ 比特(故 SHA-256 的碰撞安全约 128 位)。

直觉上:一年有 365 天,你可能觉得需要接近 365 人,才有两个人生日相同。实际上:23 个人中,两人生日相同的概率已经超过 50%,70 个人中,这个概率超过 99%。 原因在于:我们不是寻找“某个人与我同生日”,而是寻找“任意两个人生日相同” 生日攻击是一种利用概率论中“生日悖论”的密码学攻击方法

4. 性质间的蕴含关系(Relations)

定理

关系总览

  1. 抗碰撞 ⇒\Rightarrow 目标抗碰撞(CR ⟹ TCR),反之不成立。
  2. 单向性 ⇏\not\Rightarrow 抗碰撞。
  3. 抗碰撞 ⇏\not\Rightarrow 单向性。 :::

直觉上 (1) 显然:能抵御"自由选两个输入撞车",自然也能抵御"给定一个再去撞"。下面给出 (2)(3) 的反例构造,这类"用反例分离两个安全概念"的技巧在本课会反复出现。

反例 A:抗碰撞 ⇏\not\Rightarrow 单向(CR 不蕴含 OW) 设 f:{0,1}n→{0,1}nf:\{0,1\}^n \to \{0,1\}^n 抗碰撞。定义 H(x)=f(x) ∥ x(∥ 为拼接).H(x) = f(x) \,\|\, x \quad(\| \text{ 为拼接}).

  • 它仍抗碰撞:若 H(x)=H(x′)H(x) = H(x'),则尾部 x=x′x = x',根本不存在碰撞。
  • 但它完全不单向:输出里直接附带了 xx,看一眼就能读出原像。 :::

反例 B:单向 ⇏\not\Rightarrow 抗碰撞(OW 不蕴含 CR) 设 f:{0,1}n→{0,1}nf:\{0,1\}^n \to \{0,1\}^n 单向。定义 H(x1,x2)=f(x1).H(x_1, x_2) = f(x_1).

  • 它仍单向:要反推需恢复 x1x_1,难度等同求逆 ff。
  • 但碰撞平凡:固定任意 x1x_1,随便改 x2x_2 即得碰撞(输出只依赖 x1x_1)。 :::

🔎 要点:单向性与抗碰撞是正交的两件事——前者关心"能否反推输入",后者关心"能否制造重复输出"。选择上层协议所需的性质时必须对号入座(见下节)。


5. 应用与所需性质(Applications)

应用做法所需性质
口令存储(Password Storage)存 h(PW)h(\text{PW}) 而非明文口令单向性
文件完整性(File Integrity)安全保存 hF=h(F)h_F = h(F),重算比对目标抗碰撞(TCR)
数字签名(Digital Signatures)签名其哈希 σ=Sign(sk,h(M))\sigma = \mathrm{Sign}(sk, h(M))抗碰撞(CR)
承诺(Commitments)公布 c=h(r∥x)c = h(r \| x)(rr 随机),开启时给出 (r,x)(r,x)单向 + 抗碰撞 +(保密所需的额外性质)

要点解释:

  • 口令存储:泄露哈希不应泄露口令 → 需单向性。(实践中还需加盐 + 慢哈希防字典/彩虹表。)
  • 文件完整性:只要攻击者无法对给定文件伪造同哈希的篡改版 → TCR 足矣。
  • 数字签名:签名作用在哈希上,攻击者若能找到 h(M)=h(M′)h(M) = h(M') 的碰撞即可发动**替换攻击(substitution attack)**用合法签名冒充另一消息 → 需 CR。若假设 MM 公开,则不需要单向性。
  • 承诺:随机数 rr 提供隐藏性(hiding),抗碰撞提供绑定性(binding,不可反悔)。

6. 形式化定义(Formal Definitions)

定义 4(可忽略函数 · Negligible function) μ(λ)\mu(\lambda) 可忽略,当且仅当:对任意多项式 pp,存在 λ0\lambda_0,使得对所有 λ>λ0\lambda > \lambda_0 有 μ(λ)<1p(λ).\mu(\lambda) < \frac{1}{p(\lambda)}.

直觉:可忽略 = 比任何多项式倒数都更快趋于 0,即"实际上永不发生"。

定义

定义 5(单向函数 · One-Way Function, OWF) H:{0,1}∗→{0,1}nH:\{0,1\}^{*} \to \{0,1\}^{n} 是单向函数,若对任意概率多项式时间(PPT)敌手 A\mathcal{A},存在可忽略函数 μ\mu,使得对每个安全参数 λ∈N\lambda \in \mathbb{N}: Pr⁡[ H(x′)=H(x) ]≤μ(λ),\Pr\big[\, H(x') = H(x) \,\big] \le \mu(\lambda), 其中 x←R{0,1}λx \xleftarrow{R} \{0,1\}^{\lambda},x′←A(H(x))x' \leftarrow \mathcal{A}(H(x)),概率取自 xx 与敌手的随机性。

🔎 关于这条定义的三处要点:

  1. 概率对 xx 的随机选取取期望——防止敌手挑"易解"的输入(不能让敌手自己选 xx)。
  2. 敌手不需恢复原始 xx;只要输出任意一个原像 x′x'(满足 H(x′)=H(x)H(x') = H(x))即算成功。
  3. 可忽略的成功概率是可达的:敌手随便猜一个 x′←R{0,1}λx' \xleftarrow{R}\{0,1\}^\lambda 就有微小成功率;即便猜 poly(λ)\mathrm{poly}(\lambda) 次再验证,成功概率仍可忽略。故"可忽略"而非"绝对为零"是恰当门槛。

定义

定义 6(抗碰撞函数族 · Collision-Resistant family) 函数族 {Hλ}\{H_\lambda\} 抗碰撞,若对每个 λ\lambda、每个 PPT 敌手 A\mathcal{A},A(1λ)\mathcal{A}(1^\lambda) 输出满足 Hλ(x)=Hλ(x′)H_\lambda(x) = H_\lambda(x') 的不同 x,x′x, x' 的概率可忽略。概率空间取敌手内部随机性,以及 HH 中可能的随机性(HH 本身可为确定性)。

⚠️ 为何要"函数族"而非单个函数:对任意固定确定性 hh,碰撞 (x,x′)(x,x') 客观存在(鸽笼原理),于是"存在一个直接输出该碰撞的敌手"——只是我们不知道它长什么样。用密钥/索引参数化的函数族配合非一致敌手模型,才能让抗碰撞的形式化定义自洽。


7. 习题(Exercises)

例

习题 1(OWF) 设 ff 单向,定义 g(x1,x2)=f(x1)⊕x2g(x_1, x_2) = f(x_1) \oplus x_2。分析 gg 的单向性。 提示:x2x_2 像一次性掩码,输出对 x2x_2 是满射且均匀——给定 yy 能否轻易找到某个 (x1′,x2′)(x_1', x_2') 使 gg 命中?这与"恢复 x1x_1"是不是一回事?

例

习题 2(CR) 给定抗碰撞的 h1,h2h_1, h_2,判断 h(x,y)=h1(x, h2(y))h(x,y) = h_1(x,\, h_2(y)) 是否抗碰撞。 提示:分情况——碰撞要么发生在内层 h2h_2(撞出相同中间值),要么发生在外层 h1h_1。逐层归约到 h1h_1 或 h2h_2 的抗碰撞性。


8. 小结(工程视角)

  • 三个核心性质互相独立,按上层需求选择,别用错。
  • 输出长度决定安全级别:碰撞安全 ≈ n/2n/2 位,原像安全 ≈ nn 位。
  • 口令场景仅有单向性不够,必须加盐 + 慢哈希(bcrypt / scrypt / Argon2)。
  • RO 模型是证明工具,落地用 SHA-2/SHA-3 替代,注意其间存在理论缺口。

我的理解

抗碰撞、单向性和伪随机性回答的是不同问题;把一种性质代替另一种使用,是密码协议常见的设计错误。