摘要

  • RFC 2410 用恒等函数定义 NULL,规定密钥长度和 IV 长度都为零。它让“不要机密性”成为 ESP 安全关联中的明确选择,而不是靠省略字段或私下约定表达。
  • NULL 本身不提供任何安全服务,但 ESP 可以另配强完整性算法。普通 ESP 报文又不会向路径上的设备确定性地声明自己使用了 NULL;可见性、识别方法与检查权限始终是不同事实。

NULL 算法最诚实的地方,是它从不假装改变输入。RFC 2410 给出的公式只有一行:NULL(b) = I(b) = b。送进去什么,出来仍是什么。

文件用古罗马人和缺少零符号的传说开玩笑,真正的工程部分却异常严谨。供 IKE 提取的密钥长度必须为零比特,初始化向量长度也必须为零比特;算法无状态,名义块长为一个字节。两套独立实现不需要猜测“没有加密”在协商和报文格式中究竟应怎样表示。

这正是命名一个空操作的价值。如果只把加密字段删掉,不同实现可能把缺省、错误、未配置和主动选择混为一谈。把 NULL 放进加密变换的位置,双方就能使用同一套提议、选择和安全关联机制,明确约定只要完整性,不要机密性。

“加密变换”这个栏位没有赋予 NULL 保密能力。RFC 2410 直说:NULL 不提供机密性,也不单独提供其他安全服务。它只是表示 ESP 不应用加密。安全性来自与它并列选择的认证或完整性算法。

因此,ESP_NULL 与裸 IP 不是同义词。若配合强认证算法,它可以验证数据来源和连接无关的完整性,同时让载荷保持可读。RFC 2410 将这种服务与 AH 比较,又明确指出覆盖范围不同:ESP_NULL 的认证计算不覆盖 AH 所保护的那些 IP 头部部分。

比较不能被扩大。两者使用相同认证算法时,缺少机密性并不必然让 ESP_NULL 在密码学上更弱;但报文格式、NAT 穿越、策略约束和可观察边界仍不相同。相似的安全服务不是相同的运行事实。

1998 年的 RFC 2406 要求每个 ESP 安全关联至少选择一种密码学上足够强的加密或认证算法。后来的 RFC 4303 延续了这个不变量:机密性与完整性各自在特定条件下可以为空,但二者不能同时为 NULL。ESP 外壳不能成为没有任何保护的标签。

这使单独记录 ENCR_NULL 远远不够。它只能说明机密性槽位的选择。审计还必须回答:完整性算法是什么,密钥从何而来,回放检查如何设置,策略是否允许只做完整性,入站与出站 SA 是否真正安装,报文验证是否成功。

同一个变换也不能单凭名称判定为降级。如果本地政策主动允许只做完整性,NULL 就是正确结果。如果政策要求机密性,而协商或配置错误接受了 NULL,它才可能成为未授权降级的证据。区分两种情况的不是注册号,而是版本化政策与协商记录。

在 IKEv1/IPsec DOI 注册表中,ESP_NULL 得到编号 11。当前 IKEv2 变换注册表也把 11 列为供 ESP 使用的 ENCR_NULL,同时注明它不能用于保护 IKEv2 本身。同一个数字必须结合所属注册表、变换类型和协议语境解释。

注册表解决的是共同词汇,不是运行证明。它说明某个值应如何解析,却不能说明某次协商曾提出或接受它,更不能说明内核已把它写入 SA。RFC 9395 后来把 IKEv1 及相关文件转为历史状态并关闭旧注册表,但并未把 ENCR_NULL 列入被淘汰的加密算法。

现代 ESP 指南仍保留这个机制。RFC 8221 要求实现 ENCR_NULL,使 ESP 能够提供仅认证服务;文档还指出,在 NAT 环境中,ESP 的这一用法往往比 AH 更合适。“必须实现”保障互操作能力,不等于“必须启用”,更不等于任一具体 SA 已经使用。

真正微妙的分界在观察者位置。两端拥有安全关联状态,能确切知道自己协商了哪项变换。路径上的普通中间设备只看到 ESP 外层与 SPI,未必拥有把 SPI 映射到 SA 的可信状态。

普通 ESP 报文没有一个面对所有观察者的公开位,直接写明“载荷已加密”或“这里使用 NULL”。一段密文可能偶然看似协议结构,一段明文也可能因为封装和填充难以识别。只看单个报文,分类不是确定事实。

企业网络却可能希望对仅做完整性的流量执行恶意内容检测、访问控制或审计。把密文误当明文会误解析;把明文误当密文又可能形成绕过检查的通道。观察设备需要的不只是字节,还需要关于保护服务的可靠说明。

RFC 5840 提出 WESP,正因为普通 ESP 无法让中间设备确定区分加密流量与只做完整性的流量。WESP 增加了明确的包装与协商能力,使这类可见性成为协议事实。它提供一种选择,却没有证明所有设备都曾部署它。

RFC 5879 则记录了不改动既有端点时的启发式识别方法。观察者检查可能的内部协议、长度和校验关系,尝试判断载荷是否为 ESP-NULL。启发式可以帮助过渡,但它的输出仍是推断,不是端点用 SA 状态作出的认证声明。

这份文档还限定了管理场景:检查通常发生在同一组织可控制的网络中,政策必须防止端点通过选择真正的加密来绕过检查。也就是说,识别算法只有与可执行的共同政策结合才有意义。互联网任意路径上的第三方不能因为看见可读字节就获得检查资格。

确定可见性也不等于获得权限。WESP 能回答“是否使用机密性”,却不能回答“谁可以读、出于什么目的、保留多久、如何追责”。技术可读性属于观察层,检查授权属于权力与责任层。

接收端的证据链还要继续。入站和出站 SA 是两个对象;协商完成不证明双方都安装成功。完整性验证通过不证明回放窗口接受。IPsec 处理完成不证明内层防火墙放行。到达传输层也不证明应用提交了结果。

因此,一个可信事件不能只写“ESP 已保护”。它应把对端身份、政策版本、提议与选择、两个方向的 SPI、加密与完整性算法、安装回执、序列状态、报文计数、中间设备的识别方法、检查授权以及应用结果分别保存。

这里可以直接套用 Lu Heng 对现实层的区分。RFC 与注册表定义符号;协商形成两端约定;SA 安装形成运行状态;报文成为观察对象;中间设备产生分类;组织政策授予或拒绝检查;应用才给出结果。任何一层都不能借用下一层的证明。

代理问题也随之显现。标准作者不替运营者选择政策,IKE 守护进程不替内核证明安装,内核不替检查设备证明分类,设备厂商不替数据所有者授予权力,安全团队不替应用声明成功。一个绿色“IPsec”图标往往让最容易出数的代理人代替所有人发言。

最小初始规范的优点正在这里。共同层只需要严格规定互操作所必需的 NULL 语义和参数。是否接受只做完整性、是否部署 WESP、是否允许检查以及如何保存证据,都可以留给承担后果的参与者。后续变化只有在实现、部署、验证和采用之后才成为现实。

RFC 2410 把“不做某事”规定得极其精确。后来十余年的可见性工作则提醒我们:两端精确知道的事实,不会自动变成所有观察者都能确定知道、更不会变成所有观察者都有权使用的事实。

来源