2. 密码学安全模型:语义安全、CPA、CCA

讲可搜索加密之前,得先把密码学安全模型搞清楚。你想想看,如果连安全模型都说不清,那怎么证明你的方案是安全的呢?我见过不少项目,代码写得花里胡哨,结果安全模型一摆就露馅了。

安全模型说白了就是一套“游戏规则”。它定义了攻击者能做什么、不能做什么,以及什么样的攻击结果算“攻破”。我习惯把安全模型比作拳击擂台:攻击者有自己的“攻击能力”,防守方(加密方案)要在给定能力下扛住。今天我们就聊三个最基础的擂台规则:语义安全、选择明文攻击(CPA)安全和选择密文攻击(CCA)安全。

2.1 语义安全(Semantic Security)

语义安全是由 Goldwasser 和 Micali 在 1984 年提出的概念,它是现代密码学安全的基石。

核心思想:攻击者在看到密文后,对明文的了解程度不应该比没看到密文时更高。换句话说,密文不泄露任何关于明文的额外信息(除了长度)。

我在项目中遇到过这样的情况:有人给每个用户的身份信息都用同一个密钥加密,结果密文长度直接暴露了用户类型——长度短的是 VIP,长度长的是普通用户。这就是语义安全没做到位,因为长度信息是允许泄露的,但当你允许长度泄露时,其他信息必须被完美隐藏。

语义安全的游戏(IND 游戏雏形):

  1. 挑战者生成密钥。
  2. 攻击者选择两个等长明文 m₀ 和 m₁,提交给挑战者。
  3. 挑战者随机选择 b ∈ {0,1},加密 m_b 返回密文 c。
  4. 攻击者收到 c,猜测 b'。如果 b' = b 的概率显著大于 1/2,则方案不安全。

这个游戏就是后来 IND(不可区分性)的雏形。语义安全本质上要求:任何多项式时间攻击者,在上述游戏中的优势可忽略。

2.2 选择明文攻击(CPA)

CPA 安全在语义安全的基础上,给了攻击者更大的权限。

攻击者能力:可以任意选择明文,并获得对应的密文。你可以理解成攻击者有一个“加密预言机”,想加密什么就加密什么。

为什么叫“选择明文攻击”?因为攻击者可以主动选择对他有利的明文去试探。比如,在可搜索加密场景中,服务器可能知道某个关键词的陷门(相当于加密了的查询),然后它可以用这个陷门加密一批候选关键词,看哪个匹配。这就是活生生的 CPA 场景。

我建议你记住这个结论:对于公钥加密方案,语义安全等价于 IND-CPA 安全。因为攻击者拿着公钥,随时可以自己加密任意明文,所以他天然就拥有 CPA 能力。但在对称加密中,这两个概念不完全一样——对称加密下,CPA 安全比语义安全要强。

语义安全 vs IND-CPA 比较
维度语义安全IND-CPA
攻击者能力只知道密文可加密任意明文
安全归约较直观更可证明
典型应用理论分析实际安全定义
公钥密码等价于 CPA标准要求

避坑指南:我曾经犯过一个错,给对称加密方案写证明时,直接说“语义安全就够了”。结果方案需要对抗选择明文攻击,但我的安全模型中没包括加密预言机。后来审查者一针见血:你的密文长度里就泄露了信息,而你又允许攻击者选择明文,那长度差异一对比就暴露了关键词频率。改方案改了一周……所以,别偷懒,CPA 下长度隐私也要考虑。

2.3 选择密文攻击(CCA)

CCA 是更高一层的能力。攻击者不仅可以选择明文获得密文,还可以选择密文获得解密结果,但不能对目标密文提问。

攻击者能力:拥有解密预言机,可以解密任意非目标密文。这听起来很可怕——相当于攻击者手里有半个解密机。

刚入行时我觉得 CCA 太夸张了,现实中哪有人能帮你解密任意密文?后来做可搜索加密才发现,服务器端的陷门计算、加密索引匹配,本质上就暴露了一个“解密能力”(或部分解密能力)。你设计的方案如果只满足 CPA,攻击者可以通过修改密文某个比特,观察结果是否变化,来猜测关键词——这就是经典的“字节翻转攻击”。

CCA 安全分为两种:

  • CCA1(非自适应选择密文攻击):攻击者在看到目标密文之前,可以任意询问解密预言机。看到目标密文后,就不能再问了。
  • CCA2(自适应选择密文攻击):即使看到目标密文后,攻击者仍然可以询问解密预言机,只是不能直接问目标密文本身。这是最强的安全模型。

注意:绝大多数现代加密方案都要求满足 IND-CCA2 安全。比如 AES-GCM 和 RSA-OAEP。如果你的可搜索加密方案不支持 CCA,很可能在 real world 中被侧信道或错误消息攻击利用。

2.4 三种安全模型的关系

这三种模型不是割裂的,而是层层递进。语义安全 → CPA 安全 → CCA 安全,就像三级台阶。你越往上走,攻击者能力越强,方案越难设计。

我一般在看时,第一个动作就是翻到安全模型定义那页,看它用的是 CPA 还是 CCA。如果可搜索加密只给了 CPA 证明,那后面大概率需要额外防护措施。

密码学安全模型关系图 安全定义(基础) 语义安全 IND-CPA 安全 IND-CCA 安全 攻击者仅能获取密文 无法获得任何明文信息(除长度) 攻击者可加密任意明文(加密预言机) 不能解密,只能加密 攻击者可解密任意非目标密文 (解密预言机 + 加密预言机) 安全性等级递增 CCA > CPA > 语义安全

2.5 如何选择安全模型

你问我在实际项目中怎么选?我的经验是:

  • 对称加密 + 无主动攻击:至少要求 CPA 安全。比如文件加密,攻击者拿不到加密服务。
  • 公钥加密:必须 CPA 安全(因为公钥本身就是加密预言机),但实际部署中尽量用 CCA 安全方案,因为错误消息、时间侧信道都可能变成“隐式解密预言机”。
  • 可搜索加密:取决于模型——如果服务器是 honest-but-curious(半诚实),CPA 有时够用;但如果有恶意服务器,必须考虑 CCA 安全。我曾见过一个方案,声称是 CCA,结果它的“解密预言机”只检查格式不检查完整密文,最终被 malleability 攻击拿下。

总结一句:安全模型不是越高越好,但低到连 CPA 都不满足的方案,基本等于裸奔。