摘要
- RFC 1969 把前一只 PPP 包的最后一个密文块当成下一只包的 CBC 输入,节省了逐包重建起点的代价,也让解密能力依赖包外状态。
- 初始 64 位 nonce 在 ECP 协商中明文传递,再经共享 DES 密钥变成第一只包的链式输入;16 位序列号暴露顺序缺口,但二者都不认证端点,也不保护密文不被修改。
- 若
N-1丢失,N因缺少前一密文末块而无法解密;只要N的密文本身收到,接收端便可用其末块解开N+1。链条恢复了,N-1与N的明文没有回来。
一只不能读、却不能扔的包
许多恢复机制会把出错数据立即丢弃。RFC 1969 给出一个反直觉的例外:即使包 N 已经无法解成明文,它的密文仍有价值。只要保留最后 64 位,这个末块就能成为 N+1 的 CBC 起点。
原因在于 RFC 1969 没有让每个 PPP 包重新开始。第一只包之后,发送端取前一只包的最后密文块作为新包的 C[0];接收端必须按相同顺序做同一件事。若 N-1 消失,接收端缺少解开 N 所需的输入。可是 N 的密文是完整收到的,所以其最后一块不需要先被解密,也可以直接供 N+1 使用。
于是一次丢包形成两只包宽的明文空洞。第一只是根本没有到达的 N-1,第二只是到了却打不开的 N。从 N+1 起,链式计算重新成立。这不是纠错,不是重传,更不是把空洞填回去;它只是把后续解密能力恢复到可运行状态。
CBC 为什么越过了包边界
RFC 1969 信息记录显示,它于 1996 年 6 月以 Informational 发布,目标是在 PPP Encryption Control Protocol 已经协商完成后,给出一种具体的 DES 承载协议。DES 以 64 位分组工作,CBC 在一个包内让每块明文先与前一密文块异或,再用 56 位密钥加密。RFC 1969 进一步把这条链延伸到了下一只包。
连续链有两项实际好处。它不必在每个加密包里携带新的初始化向量;相同的明文片段位于不同包时,也不会因为逐包回到同一起点而轻易生成同样的密文模式。代价是,PPP 的包边界不再是密码状态边界。独立截获一只包,并不等于拥有解开它的全部输入。
这正是效率与恢复耦合。省下逐包状态,就必须保存跨包状态;让密文流连续,就必须知道包在加密序列中的顺序。本文因此不重述 RFC 1968 的通用 ECP 状态机。我们从 ECP 已到 Opened、单向算法已选定处开始,只问 DESE 数据路径实际留下什么证据。
nonce 在阳光下,密钥在规范之外
DESE 配置选项总长 10 字节,其中 8 字节是 Initial Nonce。接收方把 nonce 提供给对端,用于对端发来的第一只加密包。RFC 建议每次 ECP 协商都换一个值,以降低重放风险;它甚至给出“1970 年以来的秒数加当前秒内纳秒数”的例子。
nonce 明文传输并非缺陷误写,因为它不是秘密。第一只包的 C[0] 是 E[k](Initial Nonce):公开 nonce 先经过双方掌握的共享 DES 密钥。接收方知道自己发出的 nonce 和同一密钥,才能重建相同起点。第二只包以后,nonce 退出数据路径,前包的密文末块接过位置。
这三个对象承担不同职责。nonce 使每次协商的起点有机会不同;密钥承担保密;前包末块维持连续状态。把 nonce 当作密钥,会忽略它公开可见;把成功协商当作身份认证,又越过了 RFC 1969 的边界。规范明确说共享秘密如何到达双方不在范围内,通常依靠人工配置,也可能参考 PPP authentication 或 Multilink Endpoint Identifier。
所以,一份抓包能证明对端提出了某个 nonce,不能证明某家机构、某个用户或某台受信设备持有预期密钥。一次成功解密说明某端具有兼容密钥和状态,却仍不是具名主体签发的身份证明。
16 位序列号只负责把缺口照亮
ECP 进入 Opened 后,DESE 第一只数据包的显式序列号为 0,随后在 16 位空间递增。接收端比较相邻值,发现不连续就知道加密序列出现缺口。没有这个字段,跨包链丢失后更难判断当前密文应接在哪个状态上。
序列号并没有参加 RFC 1969 定义的消息认证。它在包中明文可见,也没有独立完整性保护。它能回答“观察到的编号是否连续”,不能回答密文有没有被改、缺口为何产生、发送方是谁,甚至不能单独区分网络丢包、重排、主动干预和本地丢弃。
能解密也不是防篡改证书。没有额外完整性机制的 CBC 只提供有限的保密属性,密文可被有结构地改变。RFC 2419 在取代原规范时把这条边界说得更直白:只处理 confidentiality,不提供 integrity、authentication 或 nonrepudiation,也不保证抵抗 replay、cut-and-paste 与 active tampering。
因此,序列号不是没用,而是用途必须保持狭窄。它是单一 DESE 方向中的顺序告警,不是安全封印。
八字节尺子如何挤压 MRU
DES 只吃八字节整块,PPP 的 Protocol 与 Information 字段却未必恰好对齐。RFC 1969 允许对带有内部长度的 IP、IPX、XNS、CLNP 追加随机尾字节,因为接收端可按内部长度截断;对桥接等可能被尾随垃圾改变解释的协议,则引入自描述填充。
这套自描述方法来自 RFC 1570。它还有一个容易漏算的角落:如果原文已经八字节对齐,但最后几个字节恰好长得像填充尾巴,为避免接收端误删,发送方可能再加完整八字节。填充不是单纯“向上取整”,其上限由末尾内容决定。
RFC 给出的 MRU 算例很具体。若 PFC 已协商,原 MRU 又恰为八的倍数,满尺寸数据加一字节 Protocol 后需要七字节填充;再加两字节序列号和外层协议效应,DESE Information field 可比原包大 10 字节。PPP 各配置选项相互独立,协商 DESE 不会自动把 MRU 调大。
这也暴露 RFC 1969 的互操作薄弱处:发送方必须判断哪些内层协议有可靠长度、哪些会被垃圾尾巴破坏。不同实现若分类不同,密码计算都正确,最后仍可能对明文边界产生分歧。
RFC 2419 取代它,不是因为换成了 3DES
RFC Editor 的 RFC 2419 记录 明确标注其取代 RFC 1969。后继文档第 8 节也直接列出差异:所有明文包统一使用一种自描述填充;这套规则与 PPP 单独的 SDP 选项是否协商无关;最大填充固定为 8;接收端若发现填充字节不符合模式,应丢弃帧。
由于新旧规则可能让同一密文解出后被不同解释,DESE-bis 获得新的 ECP 类型 3。旧 DESE 类型 1 被弃用,遵循 RFC 2419 的实现不得主动提出,并必须拒绝收到的旧类型。今天的 IANA PPP 编号表 仍保留这条谱系。
RFC 2419 还进入 Standards Track,并把安全边界写得更完整。它没有用 3DES 替换 DES;PPP Triple-DES 另见 RFC 2420,使用 ECP 类型 2。把两者混同,会掩盖真正的取代原因:统一填充和解释规则,用新编号阻止静默版本混配,再加上更清楚的规范文字。
出口限制留在页边的一道痕迹
RFC 1969 说 DES 已被广泛研究和实现,随后注明:虽然引用资料中可找到 ECB 模式的源代码,美国出口法律禁止把“可直接编译”的源码放进本文档。RFC 2419 两年后仍保留这句话。
这是一条可以直接从原文验证的历史痕迹。它说明 1990 年代的密码软件出口限制影响了标准文档能携带什么内容。但它不能证明某个厂商是否出口、某段代码是否合法,也不能从“文档没有源码”倒推出实际部署或安全强度。缺失的代码是文档来源史的一部分,不是运行证据。
IETF Datatracker 与 RFC Editor 能证明文档身份、状态和取代关系。抓取 RFC 1969 errata 页面 时未得到可用正文,所以本文不宣称“没有勘误”。
把一盏绿灯拆成五张收据
可信记录至少分五层。第一层是 ECP 配置:方向、DESE 类型、nonce 和所引用的密钥身份,但不记录密钥本身。第二层是传输顺序:16 位序列号与缺口。第三层是密码状态:本包实际使用哪一个前置密文末块。第四层是明文重建与填充校验。第五层才是 RFC 1661 下 PPP 是否接受、是否交给上层,以及应用是否回执。
DESE 最多走到第四层。密码运算成功,帧仍可能因填充或 PPP 规则被拒;PPP 上交成功,应用仍可能失败。反过来,序列缺口可以准确预测多一只不可读包,却说不出业务损失。
Heng Lu 的 Running-Code Primacy 要求书面状态与可观察运行在扩张主张前相遇;Minimum Initial Specification 要求只给字段完成其功能所需的最小权威;Reality Layers 防止把符号直接抬升为结果,Reality, Not Advocacy 则要求揭示结构而不虚构动机。这些文章是编辑方法,不是 RFC 历史证据。
会员简报
档案背景详情
使用相应会员等级登录,即可解锁完整简报与来源注释。
仅限 Strategic Circle
Strategic Circle
所有读者均可浏览。加入并登录后可解锁档案简报。
加入 Strategic Circle仅限 Leadership Alliance
Leadership Alliance
符合条件的 IP 资产所有者和管理层可登录查看 Leadership Alliance 简报。
加入 Leadership Alliance

