摘要

  • 从 RFC 733 开始,生成消息标识符的系统就必须保证唯一性;新修订应换新 ID,而传输途中增加轨迹字段不必改变原有身份。
  • In-Reply-To 与 References 把 ID 变成会话图的边。Netnews 更进一步:每台服务器记住见过的 ID,重复到达即丢弃,分布式泛洪因此能在本地终止循环。
  • 这个名字不是签名或内容哈希。Netnews 有意把相同 ID 当作同一文章,即使正文不同;可预测的 ID 因而可能被抢先占用,压住本应传播的文章。

字节已经变化,消息仍是原来的消息

邮件进入传输系统后,中继会在顶部加入 Received。存储对象不再与提交时逐字节一致,但中继并没有改写作者的主张,也没有创造一个修订版,所以原来的 Message-ID 继续存在。

相反,作者若改变要表达的命题,并把它作为新版本发出,即使大部分文本没有动,也应获得另一个标识符。1977 年的 RFC 733 已经这样划界:Message-ID 只指向某个消息的一次具体实例或版本,后续修订应使用新 ID,唯一性由生成它的主机保证。

1982 年的 RFC 822 延续了这项责任。标识符首先供机器读取,不必对人有意义。它既不是主题摘要,也不是人员身份,而是某个已声明消息版本的稳定把手。

不经过中央分配也能组成全局名字

RFC 5322 的规则很直接:msg-id 必须全局唯一,生成者必须保证这一点。标准却没有设立逐封邮件发号的服务。

办法是拆分命名空间。@ 右边适合放域标识,生成者在左边放入自己能在该域范围内保持唯一的值,例如时间再加序号或进程相关成分。全局可区分的范围与本地记账拼在一起,就能产生全局名字,而不必为每个名字执行一次全球协调。

它长得像地址,却不能按地址使用。右侧域帮助划分唯一性责任,不代表邮箱,不要求此刻能够解析,也不证明发件人控制该域。左侧字符同样不应被下游系统猜成业务语义。

RFC 5322 还明确指出,语义决定身份。轨迹字段与重发字段可能改变语法外观,却不一定创造新消息;是否更换 ID,取决于发件人打算表达的是原消息还是另一消息,而不是某个字节是否变化。因此 Message-ID 不是校验和,也不是 SMTP 投递事务号。

回复第一次成为可携带的边

名字可以被别的对象指向时,价值才真正展开。In-Reply-To 保存父消息的 ID;References 先继承父消息已有的祖先,再附上父 ID。即使邮件从不同路径、不同时间到达,阅读软件仍可据此重建会话。

这并非现代邮件客户端后来发明的便利。1983 年的 RFC 850 要求 Usenet follow-up 延长原文章的 References,并说明用途:界面可把文章归为一次对话,读者甚至能屏蔽整段对话而无需退出新闻组。RFC 1036 保留了这套构造。

关系图也有边界。RFC 5322 指出,许多实现倒序遍历时假定每条回复只有一个父节点,而多父回复如何构造并没有完整定义。References 是对祖先关系的声明,不证明回复者理解过原文,更不证明双方作者身份。

每台服务器都把 ID 变成自己的记忆

Usenet 的对等泛洪会让同一文章从不同邻居抵达。如果每次抵达都再次转发,环路就可能永远运转。RFC 1036 描述的 history 机制让每台主机按 Message-ID 记录见过的文章;相同 ID 再来,立即丢弃。Path 可以提前避免把文章发给已经走过的站点,但仅靠本地 history 也足以切断循环。

这是一种没有中央完成标记的收敛。每个站点只拿到名字、自己的记忆和本地决定。面向人的会话引用,由此也成了分布式副本抑制键。

同名会压过不同正文

RFC 5536 把取舍写得很清楚:Netnews 把相同 Message-ID 的文章视为同一文章,不管头部或正文是否不同。它限制语法与长度,并要求保留大小写,使服务器可以直接比较八位组;全局唯一性还应跨越使用这种标识符的协议,尤其是邮件与 Netnews。

高效比较也让碰撞获得力量。若攻击者预知尚未发布文章的 ID,并先投递另一个同名对象,后来的目标文章可能因“已经见过”而被拒绝。RFC 5536 因此建议让 Netnews ID 不可预测。出错的不是内容摘要,因为这里根本没有摘要;出错的是分布式名字账本先接纳了错误声明。

这个名字从未证明什么

Message-ID 解决引用,不解决信任。它不签名正文,不认证 From,不标识 SMTP envelope 事务,不证明读者看过,也不保证同 ID 的副本字节相同。相同 ID 可能掩盖碰撞,不同 ID 也可能承载完全一样的文字。

这份克制正是设计能够延续的原因:源端负责命名,传输可加轨迹但不夺取命名权,邮件软件负责回复边,新闻服务器负责本地 history 与碰撞处置,密码学证明留给另一层。

来源与证据边界

证据链包括 RFC 733、RFC 822、RFC 850、RFC 1036、RFC 2822、RFC 5322 与 RFC 5536。它们证明规范与已知风险,不提供当前碰撞率、厂商算法、部署比例或 history 保留期的全球统计。