土法炼钢兴趣小组的算法知识备份

【密码学百科】Kerckhoffs 原则与现代密码设计哲学

目录

1883 年,荷兰语言学家 Auguste Kerckhoffs 在法国军事期刊上发表了一篇不到二十页的论文,却为此后一百四十余年的密码学发展定下了基调。他提出的六条原则——尤其是第二条”系统的安全性不应依赖于设计的保密”——至今仍是评判一切密码方案的第一块试金石。

本文将从 Kerckhoffs 原始论文出发,逐层展开这条原则在现代密码学中的投射:为什么隐蔽不等于安全?公开竞赛如何成为密码标准化的主流范式?好的密码系统应当具备怎样的设计品味?从安全余量到误用抵抗,从形式化验证到后门争议,这些话题共同构成了现代密码设计哲学的全景。

一、Kerckhoffs 的六条原则

历史背景

19 世纪下半叶,电报的普及使军事通信面临前所未有的窃听风险。当时的军用密码系统——如 Vigenere 密码的各种变体——普遍依赖于算法本身的保密性:一旦敌方获悉编码方法,整个系统便告崩溃。更糟糕的是,军事密码系统往往由少数人设计,一旦设计者被俘或叛变,所有使用该系统的通信都会暴露。

Auguste Kerckhoffs(1835-1903)并非职业密码学家,而是一位精通多国语言的语言学教授。正是这种”局外人”的视角使他能够跳出当时密码学界的思维定式。1883 年 1 月和 2 月,他在《Journal des sciences militaires》上分两期发表了论文”La Cryptographie Militaire”(军事密码学),系统性地批判了当时军用密码系统的种种弊端,并提出了六条设计原则。

六条原则的原文与现代解读

以下是 Kerckhoffs 六条原则的法语原文与现代解读:

第一条:系统即使不能在理论上证明不可破解,也应在实际使用中不可破解(Le systeme doit etre materiellement, sinon mathematiquement, indechiffrable)。

现代解读:密码系统不需要达到信息论安全(Information-Theoretic Security)的层次,但必须在计算上不可行(Computationally Infeasible)地被破解。这正是现代计算安全(Computational Security)概念的雏形——我们接受理论上可以被无限算力攻破,但要求在现实算力约束下安全。

第二条:系统不应要求保密,即使落入敌手也不应造成麻烦(Il faut qu’il n’exige pas le secret, et qu’il puisse sans inconvenient tomber entre les mains de l’ennemi)。

现代解读:这是最著名的一条,也是”Kerckhoffs 原则”通常所指的含义——系统的安全性必须仅依赖于密钥的保密,而非算法的保密。算法可以完全公开,任何人都可以审查、分析,这不应削弱系统的安全性。

第三条:密钥必须易于传递和记忆,不需要笔记,且可以方便地更换(La clef doit pouvoir en etre communiquee et retenue sans le secours de notes ecrites, et etre changee ou modifiee au gre des correspondants)。

现代解读:密钥管理(Key Management)必须简洁可行。今天我们对此有了更精密的实践:密钥派生函数(KDF)、密钥交换协议(如 Diffie-Hellman)、密钥轮换策略等,都是对这条原则的延伸。

第四条:系统应能适用于电报通信(Il faut qu’il soit applicable a la correspondance telegraphique)。

现代解读:密码系统必须适配实际的通信基础设施。在今天的语境下,这意味着算法必须能在各种硬件(从服务器到嵌入式设备、从 x86 到 ARM)和各种协议(TCP/IP、TLS、QUIC)上高效运行。

第五条:系统必须便于携带,操作不应需要多人协助(L’appareil et les documents ne doivent pas exiger le concours de plusieurs personnes)。

现代解读:密码系统的部署和操作应尽可能简单,不应引入过多的运维复杂性。一个需要复杂仪式才能使用的密码系统,在实战中往往会被旁路或错误使用。

第六条:系统应便于使用,不要求使用者承受精神压力或掌握大量规则(Enfin, il est necessaire, vu les circonstances qui en commandent l’application, que le systeme soit d’un usage facile, ne demandant ni fatigue d’esprit, ni la connaissance d’une longue serie de regles a observer)。

现代解读:这条原则预见了现代密码工程中”可用安全”(Usable Security)的核心挑战——如果密码系统太难用,人类操作者必然会犯错、走捷径或干脆绕过安全机制。今天的 NaCl/libsodium 哲学和误用抵抗设计,正是对第六条原则的直接回应。

Shannon 的格言

1949 年,Claude Shannon 在其划时代论文”Communication Theory of Secrecy Systems”中提出了一个更精炼的表述:

“The enemy knows the system.”(敌人了解系统。)

这被称为 Shannon 格言(Shannon’s Maxim),本质上是 Kerckhoffs 第二条原则的现代重述。Shannon 的论述更加数学化:他用信息论的框架证明了,在分析密码系统安全性时,应当假设攻击者完全了解加密算法,唯一的未知量是密钥。

一百四十年后的持续相关性

Kerckhoffs 的原则在提出一百四十余年后不但没有过时,反而愈发重要。原因有三:

第一,逆向工程(Reverse Engineering)的门槛持续降低。在 19 世纪,获取一个密码机的设计图纸需要间谍渗透;今天,任何人都可以用反编译器、芯片显微镜或侧信道分析来揭示算法细节。依赖算法保密的时代已经终结。

第二,代码无法保密。在软件定义一切的时代,算法以代码形式存在于数十亿设备中。每一个二进制文件都是一份潜在的”泄露”。与其幻想代码不被逆向,不如从一开始就假设算法完全公开。

第三,开放审查是建立信任的唯一可行途径。没有任何组织——无论是 NSA、GCHQ 还是中国科学院——能够独自保证一个密码方案是安全的。只有将算法置于全球密码学社区的公开审查之下,经年累月的分析未发现致命缺陷,才能建立足够的信心。

二、Security Through Obscurity:为什么隐蔽不等于安全

定义与常见误解

“隐蔽即安全”(Security Through Obscurity)是指一种依赖于设计细节保密来获得安全性的做法。需要注意的是,Kerckhoffs 原则并不禁止将算法保密作为额外的防御层,它禁止的是将保密性作为唯一或主要的安全保障。这一区分至关重要:保密可以是纵深防御(Defense in Depth)的一部分,但绝不能是安全的基石。

常见的误解包括:“我们的系统是自研算法,黑客不知道怎么攻击”——这不是安全,只是尚未被分析。“我们混淆了代码,所以算法是安全的”——混淆只增加分析成本,不构成密码学意义上的安全保障。“开源密码库更危险,因为攻击者可以看到代码”——恰恰相反,公开审查是发现并修复漏洞的最有效机制。

案例一:DVD CSS(Content Scramble System)

DVD 的内容加扰系统(Content Scramble System,CSS)是隐蔽即安全失败的经典案例。CSS 使用一种专有的 40 位密钥流密码来保护 DVD 内容。其设计从未公开,DVD 论坛(DVD Forum)依赖保密协议来限制解密技术的传播。

1999 年,挪威少年 Jon Lech Johansen 参与开发的 DeCSS 工具通过逆向工程一个授权播放器的软件实现,完整还原了 CSS 算法。结果令人震惊:CSS 的有效密钥长度仅为 16 位——远远达不到任何合理的安全标准。这意味着即使算法不被逆向,暴力破解也完全可行。如果 CSS 一开始就是公开设计的,这个致命缺陷会在部署前就被发现。

案例二:GSM A5/1

全球移动通信系统(GSM)使用 A5/1 算法来加密语音通信。A5/1 的设计在 1987 年被纳入 GSM 标准时是严格保密的。然而,1994 年算法被泄露,随后密码学家 Alex Biryukov、Adi Shamir 和 David Wagner 在 2000 年发表了实时破解 A5/1 的攻击方法。

更值得玩味的是 A5/2 的故事。A5/2 是为出口管制而设计的弱化版本,其设计同样保密。1999 年被逆向后,Ian Goldberg、David Wagner 和 Lucky Green 证明 A5/2 可以在毫秒级别内被破解。保密不但未能保护 A5/2,反而掩盖了其根本不堪一击的事实,使数十亿用户在不知情的情况下使用了一个形同虚设的加密方案。

案例三:Mifare Classic

恩智浦半导体(NXP Semiconductors)的 Mifare Classic 是全球使用最广泛的非接触式智能卡之一,广泛部署于公共交通、门禁和小额支付系统。其核心是一个名为 CRYPTO1 的专有流密码算法。

2008 年,荷兰 Radboud 大学的研究团队通过芯片切割和显微镜分析,逆向还原了完整的 CRYPTO1 算法。分析揭示了多个致命缺陷:48 位密钥空间过小、随机数生成器存在严重偏差、认证协议允许离线攻击。随后,研究者开发了能在几秒内克隆 Mifare Classic 卡片的工具。恩智浦曾试图通过法律手段阻止研究结果的发表,但荷兰法院裁定学术自由优先。

密码学中的 Streisand 效应

上述案例共同揭示了密码学中的 Streisand 效应:越是试图保密的算法,一旦被破解,造成的损害越大。原因很直观——如果算法是公开的,缺陷会在部署前被发现和修复;如果算法是保密的,缺陷会在大规模部署后才被发现,届时迁移成本可能高达天文数字(想想全球数十亿张 Mifare Classic 卡片的替换成本)。

隐蔽作为纵深防御

需要强调的是,在安全性已经由公开审查的密码算法保障的前提下,适度的隐蔽可以作为额外的防御层。例如:在 TLS 连接之上再加一层应用层加密,即使 TLS 被突破,攻击者还需要理解应用层协议。又如:不公开服务器上具体使用的密码库版本,可以增加攻击者利用已知漏洞的难度。关键在于:去掉隐蔽层后,系统依然安全。

三、公开设计与密码学竞赛

DES:第一个公开标准

1977 年,美国国家标准局(NBS,即 NIST 前身)将 IBM 开发、NSA 参与修改的数据加密标准(Data Encryption Standard,DES)确立为联邦信息处理标准(FIPS 46)。这是历史上第一个完全公开的密码学标准——任何人都可以获取算法的完整规范并自行实现。

DES 的公开引发了密码学界的一场革命。首先,公开的规范催生了独立的密码分析研究。Eli Biham 和 Adi Shamir 在 1990 年代初发现的差分密码分析(Differential Cryptanalysis)和 Mitsuru Matsui 发现的线性密码分析(Linear Cryptanalysis)都是基于对 DES 的公开分析。讽刺的是,后来解密的资料显示 NSA 在 1970 年代就已知道差分分析——正是因为 DES S 盒的设计考虑了对差分攻击的抵抗。如果 DES 不是公开的,学术界可能还要晚很多年才能发现这一重要的密码分析技术。

AES 竞赛(1997-2001)

DES 到 1990 年代末期,其 56 位密钥长度已经无法抵御暴力攻击(1998 年 EFF 的”Deep Crack”机器在不到三天内破解了 DES)。NIST 于 1997 年启动了高级加密标准(Advanced Encryption Standard,AES)的公开征选过程,这成为密码学竞赛的范式。

AES 竞赛收到了来自全球的 15 个候选方案。经过初轮筛选,5 个方案进入决赛:

评估标准包括安全性、性能(软件和硬件)、算法和实现的简洁性、灵活性。2001 年 10 月,NIST 宣布 Rijndael 胜出。Rijndael 的胜出不仅因为其出色的安全性和性能平衡,更因为其设计的数学优雅性和分析的透明性——Wide Trail Strategy 提供了清晰的安全性论证。

SHA-3 竞赛(2007-2012)

SHA-1 的理论攻击(2005 年 Xiaoyun Wang 等人的碰撞攻击)促使 NIST 启动 SHA-3 竞赛。在 64 个候选方案中,Keccak 最终胜出。Keccak 采用了全新的海绵结构(Sponge Construction),与 SHA-2 的 Merkle-Damgard 结构完全不同。这种多样性本身就是竞赛的价值——如果未来 Merkle-Damgard 结构被发现存在结构性弱点,SHA-3 可以作为后备。

eSTREAM 与流密码

eSTREAM(2004-2008)是欧洲 ECRYPT 网络资助的流密码竞赛项目,旨在选出适合软件和硬件实现的流密码。最终推荐的方案包括 Salsa20(后来演化为 ChaCha20,被广泛用于 TLS 1.3)和 Rabbit 等。eSTREAM 的一个重要贡献是证明了流密码在软件性能上可以显著超越分组密码的 CTR 模式。

NIST 后量子密码竞赛(2016-2024)

面对量子计算机对现有公钥密码学的威胁,NIST 于 2016 年启动了后量子密码学(Post-Quantum Cryptography,PQC)标准化进程。经过多轮筛选,2024 年 NIST 发布了首批标准:基于格的 ML-KEM(原 CRYSTALS-Kyber)用于密钥封装,基于格的 ML-DSA(原 CRYSTALS-Dilithium)和基于哈希的 SLH-DSA(原 SPHINCS+)用于数字签名。这是迄今规模最大、参与最广的密码学竞赛。

密码哈希竞赛

2013-2015 年的密码哈希竞赛(Password Hashing Competition,PHC)旨在选出新一代密码哈希函数。Argon2 最终胜出,成为推荐的密码哈希方案,分为 Argon2d(抗 GPU 攻击优先)、Argon2i(抗侧信道攻击优先)和 Argon2id(混合模式)三个变体。

公开竞赛的价值

公开竞赛作为密码标准化范式具有不可替代的优势。首先是公开审查:候选方案在数年间接受全球密码学家的分析,任何弱点都可能被发现。其次是多样化分析:不同的分析者带来不同的攻击视角——差分分析专家、代数攻击专家、实现安全专家、形式化验证专家各司其职。再次是信心建立:如果一个方案经受住了数百名专家数年的分析而未被破解,社区可以对其建立合理的信心。最后是知识积累:竞赛过程中产生的密码分析论文本身就是宝贵的学术资源,推动整个领域向前发展。

四、安全余量与保守设计

什么是安全余量

安全余量(Security Margin)是指密码方案设计强度与已知最佳攻击之间的差距。形象地说,如果一栋建筑的设计承重是实际负荷的三倍,那么它有三倍的安全余量。在密码学中,安全余量通常用轮数或比特数来衡量。

以 AES-128 为例:AES-128 设计为 10 轮,提供 128 位安全强度。截至目前,已知的最佳攻击是 biclique 攻击(2011 年,Bogdanov、Khovratovich 和 Rechberger),其复杂度约为 2^126.1——仅比暴力搜索快了约四倍,在实际意义上不构成威胁。更重要的是,这一攻击需要攻击完整的 10 轮 AES。对于减轮版本,最佳攻击能攻破约 7 轮——这意味着 AES-128 拥有 3 轮(即 30%)的安全余量。

保守设计的哲学

在密码学设计中,保守主义(Conservatism)不是贬义词,而是一种审慎的工程美德。设计者通常会在算法中加入超过”严格必要”的轮数或状态位数,以应对未来可能出现的更强攻击。

AES 竞赛中落选的 Serpent 是保守设计的极端例子:它使用 32 轮加密,而当时最佳攻击只能攻破约 12 轮,安全余量超过 60%。相比之下,Rijndael 的安全余量约 30%。NIST 最终选择了 Rijndael,认为其安全余量”足够”,而 Serpent 为过高的安全余量付出了不必要的性能代价。这一选择至今仍有争议——一派认为 NIST 做出了正确的工程权衡,另一派认为安全余量永远不嫌多。

Wide Trail Strategy

Rijndael 的设计者 Daemen 和 Rijmen 提出了 Wide Trail Strategy(宽迹策略),这是一种系统性的设计方法论,旨在通过数学论证确保密码算法对差分攻击和线性攻击具有可证明的最低抵抗能力。

其核心思想是:通过精心选择线性扩散层(MixColumns 操作),确保任何非平凡的差分特征或线性近似必须跨越足够多的活跃 S 盒(Active S-box)。活跃 S 盒越多,差分概率的乘积越小,攻击越困难。Wide Trail Strategy 使设计者能够在算法发布之前就给出安全性的下界,而不是仅仅依靠”目前没有人攻破”的启发式信心。

可证明安全界与启发式安全

密码学中存在两种安全论证方式。一种是可证明安全(Provable Security):将密码方案的安全性归约(Reduce)到某个公认的困难问题(如大整数分解、离散对数、格上最短向量问题),证明”如果这个困难问题无法高效求解,那么这个密码方案也是安全的”。另一种是启发式安全(Heuristic Security):通过大量的密码分析尝试建立信心——“许多聪明的人试图攻破它,但都失败了”。

对称密码学(如 AES、SHA-3)更多依赖启发式安全,因为对称密码的安全性通常无法归约到标准困难假设。公钥密码学(如 RSA、椭圆曲线)则可以建立归约证明——但归约的紧致性(Tightness)和底层假设的可信度仍然是需要仔细审视的问题。

密码学设计中的预防原则

密码学设计中存在一种不对称的风险结构:过于保守的设计最多导致性能损失,过于激进的设计可能导致灾难性的安全失败。因此,密码学设计天然倾向于保守——宁可多几轮、宁可密钥长一些、宁可安全余量大一些。这种预防原则(Precautionary Principle)在密码学中的体现比在任何其他工程领域都更为明显。

五、Misuse-Resistant 设计:让错误更难发生

问题的根源

密码学有一个残酷的现实:正确的密码算法很容易被错误地使用。密码学的安全保证通常建立在严格的前提条件之上——特定的密钥长度、不重复的随机数(Nonce)、正确的填充方式、特定的参数组合。违反任何一个前提,安全保证可能瞬间瓦解。

历史上无数的安全事故不是因为密码算法被攻破,而是因为密码算法被错误使用:WEP 协议重用 RC4 密钥流导致致命攻击;PlayStation 3 的 ECDSA 实现重用了随机数 k 值,导致私钥泄露;无数应用使用 AES-CBC 但未验证消息完整性,遭受 Padding Oracle 攻击。

NaCl/libsodium 哲学

Daniel J. Bernstein 在 2012 年推出的 NaCl(Networking and Cryptography library)体现了一种激进的可用性优先设计哲学。其核心原则可以概括为:减少选择、安全默认、难以误用。

NaCl 的设计哲学直接回应了 Kerckhoffs 第六条原则——系统应便于使用,不要求使用者承受精神压力。传统密码库(如 OpenSSL 的 EVP 接口)提供了极大的灵活性:你可以选择任意算法、任意模式、任意密钥长度、任意填充方式——但每一个选择点都是一个潜在的错误点。NaCl 采取了相反的策略:为每个常见任务提供一个经过精心选择的方案,用户无需(也无法)做出不安全的选择。

以下用伪代码对比两种设计风格:

# ---- 风格一:类似原始 OpenSSL EVP 的 API ----
# 调用者必须正确选择算法、模式、填充、IV 生成方式……
# 每一步都可能出错

from crypto import EVP

ctx = EVP.CipherContext()
ctx.set_cipher("aes-256-cbc")        # 如果选了 ECB 呢?
ctx.set_padding(PKCS7)               # 如果忘记设填充呢?
iv = os.urandom(16)                  # 如果用了固定 IV 呢?
ctx.init(key=user_key, iv=iv, mode=ENCRYPT)
ciphertext = ctx.update(plaintext) + ctx.final()
# 到这里,没有任何认证标签——调用者必须自己加 HMAC
# 如果忘了呢?Padding Oracle 攻击在等你
hmac_tag = hmac_sha256(mac_key, iv + ciphertext)
# mac_key 从哪来?和 enc_key 一样吗?
# 先加密再 MAC 还是先 MAC 再加密?顺序错了也不安全


# ---- 风格二:NaCl / libsodium 风格的 API ----
# 一个函数完成认证加密,无需选择算法或模式

from nacl import secret_box

ciphertext = secret_box(
    plaintext=message,
    nonce=random_nonce(),   # 库也可以自动生成
    key=key                 # 固定 256 位
)
# 返回值已包含认证标签,解密时自动验证
# 算法、模式、填充、MAC 全部由库内部决定
# 用户唯一需要做的是保管好 key

上面的对比清楚地展示了设计哲学的差异:第一种风格把所有决策权交给调用者,第二种风格把安全决策内化到库本身。Daniel Bernstein 将其称为”不要让用户做选择题,因为他们会选错”。

crypto_box:一个函数搞定认证加密

NaCl 的 crypto_box 函数是其哲学的集中体现。调用者只需提供收件人的公钥、发件人的私钥和消息,函数内部自动完成 X25519 密钥交换、HSalsa20 密钥派生、XSalsa20-Poly1305 认证加密。整个过程对调用者完全透明——不需要理解密钥交换、不需要选择对称算法、不需要单独处理认证。

Nonce 误用抵抗

传统的认证加密模式(如 AES-GCM)在 Nonce 重用时会发生灾难性失败——不仅当前消息的保密性丧失,密钥流的重用还可能泄露认证密钥。AES-GCM-SIV(由 Shay Gueron 和 Yehuda Lindell 设计)是一种 Nonce 误用抵抗(Nonce-Misuse Resistant)的认证加密模式。其核心思想是将认证标签同时用作 IV——如果 Nonce 被重用,攻击者最多只能检测到两条相同的明文是否相同,但不会泄露更多信息。更广义地说,MRAE(Misuse-Resistant Authenticated Encryption)概念由 Rogaway 和 Shrimpton 在 2006 年形式化定义,要求即使在最坏情况下(Nonce 重用),安全性的退化也应是优雅的(Graceful Degradation)。

密钥承诺

密钥承诺(Key Commitment)是近年来受到关注的一个微妙问题。AES-GCM 等标准 AEAD 模式允许一条密文在不同密钥下解密为不同的有效明文——这被称为”隐形蝾螈”(Invisible Salamanders)攻击。在某些应用场景中(如端到端加密的群组消息),这可以被利用来实施针对性的欺骗攻击。密钥承诺的 AEAD 方案保证每条密文只能在一个密钥下成功解密,从根本上消除了这类攻击。

AEAD 作为基线

一个重要的行业共识已经形成:认证加密(Authenticated Encryption with Associated Data,AEAD)应当是加密操作的默认基线。不提供认证的加密(如裸 AES-CBC、裸 AES-CTR)不应在新系统中使用。TLS 1.3 做出了激进的选择:完全移除了所有非 AEAD 的密码套件。这一决策的背后是无数因缺乏认证而导致的安全事故的惨痛教训。

正反案例对照:API 与协议设计的安全品味

将上述理论具象化,我们可以从现代密码库和协议中找到正反两面的鲜明案例。

正面案例:libsodium / NaCl

反面案例:OpenSSL EVP 接口与 WEP 协议

维度 正面(libsodium / NaCl) 反面(OpenSSL EVP / WEP)
算法选择 库内固定,用户无需选择 数十种组合,选错即灾难
认证加密 默认且唯一 需手动叠加 MAC,易遗漏
Nonce 管理 192-bit 随机 nonce,碰撞概率可忽略 WEP 仅 24-bit IV,数小时内必碰撞
侧信道防护 默认常量时间 需开发者自行确保
误用后果 API 设计使误用路径几乎不存在 误用路径比正确路径更短

笔者认为,「简洁即安全」是 Kerckhoffs 原则中最被低估的推论。Kerckhoffs 的第六条原则——系统应便于使用——在今天的语境下意味着:密码库的 API 设计本身就是安全架构的一部分。当一个 API 让做正确的事比做错误的事更容易时,它就在系统层面消除了一整类漏洞。反过来,当 API 将密码学决策权交给每一个调用者时,它实际上是在以整个用户群体的安全为代价换取灵活性——这笔交易几乎从来不值得。从 WEP 的覆灭到 TLS 1.3 果断砍掉所有非 AEAD 套件,历史反复证明:在密码工程中,少即是多,约束即是自由。

六、密码学标准化流程

NIST 的角色

美国国家标准与技术研究院(National Institute of Standards and Technology,NIST)是全球最具影响力的密码学标准化机构。其发布的联邦信息处理标准(Federal Information Processing Standards,FIPS)不仅对美国联邦政府机构具有约束力,在实践中也被全球工业界广泛采纳。NIST 的密码学标准化工作涵盖了对称加密(AES/FIPS 197)、哈希函数(SHA 系列/FIPS 180、SHA-3/FIPS 202)、数字签名(DSA/FIPS 186)、随机数生成(SP 800-90 系列)以及最新的后量子密码标准。

NIST 标准化流程的特点是公开、透明、接受公众评论。每一个标准草案都会经历至少一轮公开评论期,任何人都可以提交意见。这种透明性正是 Kerckhoffs 原则在标准化领域的具体实践。

IETF 的角色

互联网工程任务组(Internet Engineering Task Force,IETF)通过征求意见稿(Request for Comments,RFC)机制标准化互联网协议中的密码学应用。与 NIST 侧重于底层密码算法不同,IETF 侧重于密码算法在网络协议中的集成方式——如何在 TLS(RFC 8446)中协商密码套件、如何在 IPsec(RFC 4301 系列)中使用 AEAD、如何在 JOSE(JSON Object Signing and Encryption,RFC 7518)中表示密码学操作。

IETF 内部的密码学论坛研究组(Crypto Forum Research Group,CFRG)扮演着密码学算法与协议标准之间的桥梁角色。CFRG 负责评估和推荐密码学算法供 IETF 协议使用——例如,Curve25519 和 Curve448 正是通过 CFRG 的推荐(RFC 7748)进入 TLS 生态的。

ISO/IEC 标准

ISO/IEC JTC 1/SC 27 是国际标准化领域中负责信息安全技术的委员会。其发布的 ISO/IEC 18033(加密算法)、ISO/IEC 10118(哈希函数)、ISO/IEC 9797(消息认证码)等标准在国际贸易和合规场景中具有重要地位。

国家标准

各国也制定自己的密码学标准以适应特定需求。中国的国密标准(GB/T 系列)定义了 SM2(椭圆曲线公钥密码)、SM3(密码杂凑算法)、SM4(分组密码算法)和 SM9(基于身份的密码算法)。欧洲的 ECRYPT 网络通过定期发布的推荐算法列表(如 ECRYPT-CSA D5.4)为欧洲各国提供密码学选型参考。俄罗斯有 GOST 系列标准,日本有 CRYPTREC 推荐列表。

标准化速度与安全信心之间的张力

密码学标准化面临一个内在的张力:标准化太快,可能将未经充分审查的算法推向广泛部署;标准化太慢,可能让陈旧的、已知不安全的算法继续被使用。NIST PQC 标准化进程就体现了这种张力——从 2016 年启动到 2024 年发布首批标准,历时八年。期间有人批评进度太慢(量子计算机可能已经在路上),也有人担忧进度太快(格密码的安全性假设是否经受了足够的审查)。

七、开源与形式化验证

开源密码库的生态

当代主流密码学实现几乎都是开源的。OpenSSL 是历史最悠久、部署最广泛的密码库,支撑着互联网上大部分的 TLS 连接。Google 从 OpenSSL 分叉出的 BoringSSL 专注于简洁性和安全性,删除了大量遗留代码和不安全的算法选项。libsodium 是 NaCl 的可移植、易用的分发版本,面向应用开发者。wolfSSL 专注于嵌入式和物联网场景。Go 语言标准库的 crypto 包也是一个值得关注的实现——它完全由 Go 团队独立编写(不依赖 OpenSSL),并在设计上倾向于安全性而非灵活性。

Heartbleed:开源不等于已审计

2014 年 4 月披露的 Heartbleed 漏洞(CVE-2014-0160)是开源密码库历史上最严重的安全事件之一。这个存在于 OpenSSL 的 TLS Heartbeat 扩展实现中的缓冲区过读漏洞,允许攻击者从服务器内存中窃取最多 64KB 的敏感数据——包括私钥、会话密钥和用户密码。

Heartbleed 的启示深刻而痛苦:开源代码是公开的,但”公开”不等于”被审查”。OpenSSL 在 Heartbleed 之前长期面临资金和人力不足的问题——一个支撑着全球互联网安全基础设施的关键项目,其核心开发团队只有寥寥数人。Heartbleed 之后,Linux 基金会发起了核心基础设施计划(Core Infrastructure Initiative,CII),后来演化为 Open Source Security Foundation(OpenSSF),旨在为关键开源安全项目提供持续的资金和审计支持。

形式化验证:密码实现的未来

如果代码审查无法保证密码实现的正确性,那么什么可以?答案是形式化验证(Formal Verification)——使用数学证明来确保代码严格符合其规范。

HACL* 是一个使用 F(一种面向验证的函数式编程语言)编写的密码学库。HACL 中的每一个算法实现都经过形式化验证,证明其功能正确性(输出与数学规范一致)、内存安全性(无缓冲区溢出、无悬垂指针)和侧信道抵抗性(执行时间和内存访问模式不依赖于秘密数据)。HACL* 的代码已被 Firefox 和 Linux 内核采用。

EverCrypt 建立在 HACL* 之上,是一个经过验证的密码学提供程序(Crypto Provider)。它不仅验证了单个算法的正确性,还验证了算法选择和调度逻辑——例如,在支持 AES-NI 指令集的处理器上自动使用硬件加速,否则回退到纯软件实现,并证明这两条路径产生完全相同的结果。

Project Everest 是微软研究院主导的一个更宏大的项目,目标是构建一个从密码学原语到 TLS 协议的完整、经过形式化验证的网络安全栈。它综合使用了 F、Low(一种编译到 C 的验证语言)、Vale(用于验证汇编代码的语言)等多种工具。

JasminEasyCrypt 则从另一个方向切入:Jasmin 是一种允许开发者编写接近汇编级别的高性能密码学代码,同时支持形式化验证的语言;EasyCrypt 是一个专门用于密码学安全证明的交互式证明助手。两者的结合使得研究者可以同时证明一个密码方案在理论上是安全的(EasyCrypt),并且其具体实现正确地实例化了该方案(Jasmin)。

形式化验证代表了密码学实现的未来方向。传统的代码审查依赖于审查者的经验和注意力,而形式化验证提供了数学级别的确定性。当然,形式化验证也有其局限性:它只能证明代码符合其规范,如果规范本身有误(例如形式化了一个存在缺陷的密码算法),验证通过也无济于事。此外,目前形式化验证的工程成本仍然很高,通常只适用于最关键的密码学基础设施。

八、密码学中的争议与灰色地带

后门与密钥托管

密码学领域最持久的争议之一是政府机构是否应当在密码系统中安置后门(Backdoor)或密钥托管(Key Escrow)机制,以便在必要时访问加密通信。

1993 年,美国政府推出了 Clipper Chip——一种内置密钥托管机制的加密芯片。其设计允许执法部门在获得法院授权后解密通信内容。Clipper Chip 遭到了密码学界和民权组织的强烈反对,Matt Blaze 在 1994 年发现了其密钥托管协议的致命缺陷,最终该项目被放弃。

更为隐蔽的案例是 Dual_EC_DRBG(双椭圆曲线确定性随机比特生成器)。这个由 NIST 在 2006 年标准化的随机数生成器后来被 Edward Snowden 泄露的文件证实包含了 NSA 植入的后门。Dual_EC_DRBG 使用的两个椭圆曲线点之间存在一个只有后门持有者知道的关系,允许其从输出中恢复内部状态,从而预测所有后续输出。RSA Security 公司被曝收受 NSA 1000 万美元,将 Dual_EC_DRBG 设为其产品的默认随机数生成器。

这些事件深刻地损害了公众对密码学标准化过程的信任,也强化了 Kerckhoffs 原则的重要性:如果密码系统的安全性依赖于”没有人知道后门的存在”,那么它本质上违反了 Kerckhoffs 原则。

“天黑了”辩论

“Going Dark”(天黑了)是执法部门用来描述加密通信普及导致其监听能力下降的术语。这一辩论的核心是:强加密在保护公民隐私和国家安全的同时,也使犯罪分子和恐怖分子的通信难以被监控。

密码学界的主流立场是:任何形式的”执法访问”机制都会引入系统性的弱点,不可能只对”好人”开放。一旦后门存在,它终将被恶意行为者发现或利用。2015 年的一份由十五位密码学家联合签署的报告”Keys Under Doormats”系统性地论证了执法后门在技术上的不可行性。

负责任的披露

密码学领域的负责任披露(Responsible Disclosure)有其特殊性。当研究者发现一个广泛部署的密码方案存在实际可利用的缺陷时,面临两难:立即公开可能导致大规模攻击,但长期保密可能使得漏洞被他人独立发现并被恶意利用。

密码学社区的一般做法是:先通知受影响的厂商和标准组织,给予足够的时间(通常 90 天)开发和部署补丁,然后再公开披露。BEAST、CRIME、POODLE 等 TLS 攻击的披露过程都遵循了这一模式。

出口管制

密码学曾长期被美国政府视为军需品(Munitions),受国际武器贩运条例(International Traffic in Arms Regulations,ITAR)管控。1990 年代的”密码战争”(Crypto Wars)中,Phil Zimmermann 因发布 PGP(Pretty Good Privacy)加密软件而面临刑事调查;Netscape 浏览器的出口版本只能使用 40 位加密密钥。

虽然出口管制在 2000 年前后大幅放松,但其影响深远。许多早期互联网协议(如 SSL 3.0)中的”出口级”密码套件成为了长期的安全隐患——2015 年的 FREAK 和 Logjam 攻击正是利用了协议降级到这些弱密码套件的可能性。

量子计算的压力

量子计算的威胁给密码学标准化带来了前所未有的时间压力。Shor 算法理论上可以高效破解 RSA、椭圆曲线和 Diffie-Hellman 等基于数论困难问题的公钥密码方案。虽然目前尚不存在能够威胁实际密码系统的量子计算机,但”先收集、后解密”(Harvest Now,Decrypt Later)的威胁迫使标准化机构必须在量子计算机实际到来之前完成后量子密码的标准化和部署——这可能需要十年甚至更长时间。

专利问题

密码学中的专利问题一直是一个敏感话题。Phil Rogaway 设计的 OCB(Offset Codebook Mode)模式是公认的性能最优的 AEAD 模式之一,但其专利限制严重阻碍了其被广泛采用——尽管 Rogaway 后来为开源软件授予了免费许可。Schnorr 签名在其专利有效期内(至 2008 年)基本无法被标准化采用,这也是为什么 DSA(一种为绕过 Schnorr 专利而设计的变体)成为了美国的签名标准。Claus-Peter Schnorr 甚至在 2021 年声称证明了 RSA 是不安全的(后来被否定),引发了一场不大不小的风波。

专利与密码学的紧张关系反映了一个更深层的矛盾:密码学是关乎公共安全的基础设施,但创新需要激励。当专利阻碍了更安全方案的采用时,整个生态的安全性都会受损。

九、设计哲学总结:好的密码系统长什么样

经过前面八个章节的讨论,我们可以提炼出一套现代密码系统的设计哲学。

公开且经过充分研究的算法。这是 Kerckhoffs 原则最直接的体现。一个好的密码系统使用的所有算法都应是公开发表的、经过多年独立分析的、没有已知致命缺陷的。最好是经过公开竞赛筛选出的标准算法——AES、SHA-3、ChaCha20-Poly1305、Curve25519 等。

充足的安全余量。好的密码系统不会在安全边界上”精打细算”。它使用的参数(密钥长度、轮数、安全级别)应当留有足够的余量来应对未来可能出现的更强攻击。选择 256 位密钥而非 128 位、选择更多轮次的配置——即使今天看来”过度”——都是审慎的工程选择。

误用抵抗的 API。好的密码系统不信任其使用者会完美地遵循所有前提条件。它通过 API 设计来消除常见的误用模式:默认使用 AEAD 而非裸加密、自动生成随机数而非要求调用者提供、使用类型系统来防止密钥和数据的混淆。正如 Bernstein 所言:“不要让开发者做密码学决策。”

最小复杂度。KISS 原则(Keep It Simple, Stupid)在密码学中具有特殊的重要性。密码系统的复杂度直接影响其可分析性——越复杂的系统,越难证明其安全性,也越容易隐藏缺陷。AES 的设计之所以受到推崇,很大程度上是因为其结构的优雅简洁。

密码敏捷性。好的密码系统从一开始就为算法更换做好准备。这意味着:协议中明确编码所使用的算法标识、支持多种算法的协商机制、密钥和参数的清晰分离。TLS 的密码套件协商机制就是密码敏捷性的典范——当 RC4 被发现不安全时,只需更新配置即可切换到 AES-GCM,无需修改协议本身。

纵深防御。好的密码系统不把所有安全赌注押在单一机制上。它在多个层次上设置独立的安全屏障:传输层加密(TLS)、应用层加密、存储加密各司其职;认证和加密分离;密钥管理独立于算法选择。任何单一层次的失败不应导致整个系统的崩溃。

这些原则并非独立存在,它们相互关联、相互强化。公开的算法使充分的审查成为可能,充分的审查建立了对安全余量的信心,对安全余量的理解指导了参数选择,合理的参数通过误用抵抗的 API 传递给开发者,简洁的设计使形式化验证成为可能,密码敏捷性确保了在任何单一算法出现问题时系统可以平稳过渡。

从 Kerckhoffs 1883 年的六条原则到今天的误用抵抗设计和形式化验证,密码学的设计哲学经历了一百四十余年的演化,但其内核从未改变:安全不应依赖于秘密,而应依赖于公开的、经过验证的、可以被任何人审查的数学。

在接下来的文章中,我们将从设计哲学转向密码学最根本的原材料——随机性。没有高质量的随机数,再精妙的算法设计也不过是沙上筑塔。第四篇”随机性:密码学的基石”将深入探讨密码学对随机性的需求、伪随机数生成器的设计,以及随机性失败导致的灾难性安全事故。


密码学百科系列 · 第 03 篇

← 上一篇:威胁模型与安全目标 | 系列目录 | 下一篇:随机性


By .