摘要

  • RFC 3962 用四字节大端无符号数表示 Kerberos AES 的 PBKDF2 迭代次数:字段明确为全零时代表 4,294,967,296 次,KDC 有机会提供参数后字段仍缺失时才解释为 4096 次。
  • 高值可被伪造来耗尽客户端算力,低值又能降低攻击者试猜口令的成本;因此真正的控制是来源认证、本地上下限与分层收据,而不是追求一个永远正确的数字。

先不要把 00 00 00 00 转成整数。先问:这四个字节真的出现在消息里吗?

这是 RFC 3962 留给实现者的关键问题。它把字符串转密钥参数定义为四个字节,按大端顺序表示无符号迭代次数。但全零不是零轮,而是 4,294,967,296 轮,也就是 (2^{32})。这样编码后,能表达的最小次数反而是一。

参数不存在则走另一条路径。只有当 KDC 已有机会给出该字段、消息却没有提供时,客户端才使用 00 00 10 00,即十进制 4096。这不是站点数据库的统一推荐值,也不是乐观预认证应当盲猜的“默认值”。它只是特定上下文中“缺失”的解释。

解析器不能抹掉“在场”这个事实

全零、缺失、空缓冲区和配置默认值,在许多数据框架里很容易被压成同一个假值。这里一旦压平,工作量就可能相差 1,048,576 倍。字段的存在位不是实现细节,而是密码学语义的一部分。

RFC 3962 于 2005 年 2 月发布,把 AES 放进 RFC 3961 建立的 Kerberos 加密配置框架:AES 块长为 128 位,密钥为 128 或 256 位,消息使用 CBC 密文窃取,完整性采用 HMAC-SHA1-96。它分配了加密类型 17、18 和校验类型 15、16。今天的 IANA Kerberos 参数登记表仍保存这些编号,但登记只证明编号与规范的对应,不证明任何域已经启用或选中它们。

口令派生先用 PBKDF2 处理口令与盐,得到临时密钥,再按 RFC 3961 的派生方法,以 kerberos 常量生成协议密钥。RFC 2898 是当时引用的 PBKDF2 来源,RFC 8018后来更新了 PKCS #5 体系。这里不能把 256 位输出误写成 256 位口令强度。迭代能增加每次猜测的成本,却不能凭空补出口令没有的熵。

调高和调低都是攻击面

PBKDF2 的工作因子有一个不讨巧的对称性:攻击者每试一次要多做多少工作,合法用户计算正确密钥也要多做多少。它是成本乘数,不是只惩罚坏人的机关。

因此伪造者可以从两个方向转动旋钮。若伪造 KDC 回复并送入极高次数,客户端会长时间占用 CPU 去计算一把最终错误的密钥。RFC 允许实现设置上限来缓解拒绝服务;如果设置,上限不应低于 50,000。即使硬件很快,四十多亿轮也可能耗时极长,允许用户或系统中断计算是合理防护。

若伪造者送入极低次数,风险会反向变化。攻击者观察客户端回复后,可以用更低成本离线试猜口令。文档因此同时讨论下限。正确控制不是“越高越安全”,也不是“网络送来多少就算多少”,而是由站点治理的可接受区间,再加上参数来源是否可信。

一条仅有 iterations=4096 的日志仍然不够。它没有说明该值来自经过认证的 KDC、未经认证的错误回复、本地缓存、站点配置、字段缺失规则,还是测试开关;也没有说明客户端是否先检查上下限再开始计算。同一个数字可以是合法政策、兼容回退,也可以是攻击者输入。

乐观预认证借走了一次新鲜观察

乐观预认证试图省掉一次往返:客户端在收到 KDC 的当前参数前,就先推导长期密钥并发送受保护时间戳。猜中时更快,猜错时却暴露出参数从哪里来这个治理问题。

RFC 3962 明确说,客户端若没有额外信息,只能猜迭代次数。“几小时前同一主体使用过这个数”也不可靠,因为站点本来就可能随算力提升而上调。文档没有给一个永不过时的推荐默认值,而是建议采用站点本地配置,并让它落在同样的上下限之间。

这段历史不能被简化成“4096 曾经安全”或“50000 是答案”。硬件、口令分布与可接受延迟都会变化。规范真正留下的是控制模型:安全成本参数必须有所有者、观察时间和认证状态。乐观路径跳过了新鲜的 KDC 观察,就必须由另一套配置与更新责任补位。

推导完成只是中间收据

即使四字节解释正确、PBKDF2 顺利完成,也只得到密钥材料。RFC 4120 才规定 Kerberos V5 的票据、认证器、重放处理与完整协议流程。字符串转密钥成功不证明口令正确,不证明 KDC 接受预认证,不证明票据仍有效,更不证明应用批准请求或服务已经交付。

后续规范继续保留这些边界。RFC 4537把客户端提供的加密类型与服务端按策略选中的类型分开;RFC 6113扩展预认证框架与参数承载;RFC 8009引入 AES-CTS/HMAC-SHA2 配置;RFC 8429弃用多种旧算法。它们分别改变链条的一段,没有任何一篇把迭代次数或密钥推导提升为业务授权。

AES 构造还有另一条独立边界:密文窃取避免填充扩张,也因此暴露精确明文长度。若上层需要隐藏长度,就要自行加入混淆数据。提高迭代次数不会修补长度泄漏;一个控制不能冒领另一个控制的效果。

可审计记录至少应保留:字段存在与否、原始四字节、解析后的无符号次数、消息来源及其认证状态、本地下限与上限、实际加密类型、盐的来源、库版本、耗时与资源、中断状态,以及不泄密的推导结果。之后再分别记录预认证、票据、新鲜度、重放、应用授权和服务结果。口令与派生密钥不应进入日志。

RFC Editor 条目和 IETF Datatracker保存了发布状态与历史;RFC 3962 勘误检索在本次取证时没有返回匹配项。这只说明勘误登记的当前状态,不能外推为所有实现都没有错误。

RFC 3962 最值得记住的不是那个巨大的数,而是一条朴素纪律:零、缺失和默认值是三种不同陈述。只要协议把数十亿次计算绑在这一区别上,保留它就同时属于安全与可用性。

来源