摘要

  • RFC 9787 是 2025 年 8 月发布的 Informational RFC,而不是 Standards Track 标准。其第 9.5 节把草稿视为一种需要独立保护的状态:远程 Drafts 文件夹可能暴露明文,因此除非 MUA 明确知道成稿将以明文发送,或知道 Drafts 不可能被潜在攻击者读取,否则客户端 SHOULD 加密所有草稿。
  • 受保护草稿的加密对象范围被刻意限制在作者本人。RFC 要求草稿 MUST 只加密给用户自己的证书,或只由该用户持有的等效密钥;预定收件人不能因为自己以后可能收到这封邮件,就提前取得读取未完成文字的能力。面向收件人的加密只能在真正发送时发生。
  • RFC 同时划出一条签名边界:合规 MUA MUST NOT 用用户的日常签名密钥签署草稿,因为 RFC 认为,对未完成文字生成不可否认签名可能被理解为作者已经作出承诺。这是 RFC 给出的安全与语义理由,不应被扩大成关于合同、证据或法律责任的普遍结论。
  • 多设备续写使问题从“是否加密”转变为“谁现在有权解密、修改和发送”。另一台 MUA 不仅需要访问同一个邮箱,还必须取得能够解密草稿的私钥。RFC 明确承认,多 MUA 之间安全共享用户密钥和证书仍是未解决问题,具体机制不在本文档范围内。
  • 本文提出 Daniel Kade 的“草稿意图保管收据”,仅作为 BTW 的编辑提案,不是 RFC 9787 的要求。其作用不是保存邮件内容,而是在草稿跨设备流转并最终越过发送边界时,为权限变化留下最小化、可审计而又短期存在的证据。

一封邮件,两个不同的权威状态

理解第 9.5 节的关键,不是把 Drafts 和 Sent 当成两个文件夹,而是把它们背后的对象状态分开。

保存中的草稿仍然属于作者内部的工作对象。它可以变化,可以被另一台受作者控制的客户端重新打开,可以被覆盖或继续编辑。它的预定收件人集合甚至可能还没有稳定下来。RFC 9787 因而没有把“以后也许会发送给谁”当成“现在谁有权解密”的依据。

发送后的邮件则不同。真正发送意味着对象越过了一条外部授权边界:客户端可以开始让最终收件人获得与发送决定相符的读取能力,而邮件本身也不再只是作者私有的未完成状态。

这一区别解释了 RFC 看似反直觉的一点:即使用户最终准备发送端到端加密邮件,草稿也不应简单地提前加密给那些预定收件人。草稿阶段的保密目标不是“让未来通信参与者都能提前解密”,而是“即使草稿需要放进远程邮箱,也仍然只让作者自己读取”。

因此,同一个文字对象在生命周期中会经历两种不同的加密关系。保存阶段是作者对自己的保护;发送阶段才是作者对收件人的授权。把两者合并,会消除 RFC 试图保存的意图边界。

远程 Drafts 改变了草稿的威胁模型

RFC 9787 第 9.5 节从一个普通行为出发:许多 MUA 会把尚未发送的邮件保存在 Drafts 文件夹。如果该文件夹位于用户控制之外,例如远程 IMAP 邮箱,那么以明文保存草稿可能导致内容泄露。

重要之处在于,客户端在自动保存时未必已经知道这封邮件最终会怎样发送。用户可能继续改变决定,最终保护方式也可能尚未确定。RFC 因而给出一个偏向保护草稿阶段的规则:除非 MUA 明确知道最终邮件不会加密,或者明确知道 Drafts 文件夹不会被潜在攻击者读取,否则 MUA SHOULD 加密所有草稿。

这里存在两个不同判断。第一个判断面向最终发送方式:客户端是否确实知道成稿将以明文发送。第二个判断面向存储端:客户端是否确实知道草稿位置不会被潜在攻击者读取。只要这两个例外都不能成立,RFC 的建议就是保护草稿本身,而不是等到点击发送时才第一次考虑机密性。

但保护草稿并不等于提前建立与收件人的秘密通信。RFC 紧接着规定,草稿 MUST 只加密给用户自己的证书,或者只使用只有该用户持有的等效秘密密钥。于是,远程邮箱可以保存一个自己无法读取正文的对象,而真正的收件人也同样没有提前得到读取权。

这正是“保管”与“发送”的区别:远程系统可以保管密文,却不因此成为草稿内容的被授权读者;预定收件人可以出现在作者的计划中,却不因此成为草稿状态下的密码学参与者。

多客户端续写才是真正困难的部分

如果只有一台 MUA,作者专用草稿加密的模型相对直接:客户端保存,客户端持有解密能力,客户端再次打开。

第二台设备进入之后,问题开始变化。RFC 明确指出,另一台连接到同一邮箱的 MUA 要继续撰写该草稿,不仅必须能够取得草稿对象,还必须能够访问用户用于解密的秘密密钥。拥有邮箱访问权并不自动等于拥有草稿明文访问权。

这意味着同步可以在两个层面同时成功或失败。存储层可能已经把密文完整同步到另一台设备,但如果第二台 MUA 没有相应解密能力,那么跨设备续写仍然失败。反过来,如果为了方便续写而扩大秘密密钥的可用范围,系统又改变了哪些客户端实际上能够打开作者尚未发送的文字。

RFC 9787 的附录 A.4.1 把多个 MUA 如何高效、安全地共享用户秘密密钥材料和证书留作未来工作。这里没有一个由 RFC 9787 定义的完整跨设备草稿密钥协议。附录 A.4.2 又指出,可移动的秘密密钥机制可以成为不直接在客户端之间传送秘密材料的另一种方向,但同样没有在 RFC 9787 中形成完整的草稿协作机制。

因此,RFC 给出了清晰的安全目标,却没有把跨设备实现路径假装成已经解决的问题。这一点对于评估实现尤其重要:一个客户端可以正确理解“草稿只给作者解密”,却仍然没有解决作者如何安全地让第二个客户端成为同一个“作者端点”的问题。

日常签名密钥不能提前把草稿变成“已承诺文字”

第 9.5 节对签名的限制比对加密更尖锐。合规 MUA MUST NOT 使用用户的日常签名密钥给草稿签名。

RFC 给出的理由不是草稿不能有任何完整性机制,而是日常签名可能携带不适合未完成文字的含义。RFC 使用“不可否认签名”和“承诺”来解释风险:如果一个仍处于修改中的草稿泄露到不可信的 Drafts 存储位置,持有它的一方可能据该签名声称作者已经对尚未决定的内容作出承诺。

这里需要严格保持边界。RFC 的文字说明的是邮件安全设计中的语义风险,不是为所有司法辖区建立一种自动法律效果。签名的法律意义取决于远超该 RFC 范围的条件。能够从 RFC 直接得到的结论更窄:它不希望合规 MUA 在未完成状态下调用用户平时用于成稿签名的密钥,从而制造可能被误读的密码学证据。

RFC 同时留下一个重要但未完成的口子:如果多个 MUA 需要利用签名来协调同一用户的草稿状态,可以使用另一把不同的草稿签名密钥。文档没有定义如何协商、分发或管理这把密钥。因此,“允许另一把密钥”不是“已经存在标准化草稿签名系统”。

这里再次出现相同的设计原则:草稿需要足够的内部真实性来支持安全协作,并不意味着它应提前获得最终发送对象通常可能具有的作者承诺语义。

真正发送时,收件人才进入加密关系

RFC 9787 对这一时点的表达很直接:邮件只应在真正发送时才加密给收件人。其理由同样来自用户预期——合理的用户不会预期预定收件人可以阅读一封还没有写完的邮件。

这使“发送”成为比 UI 中一个按钮更重要的技术事件。在发送之前,收件人身份最多是作者正在形成的意图;在发送发生后,它们才成为密码学授权的外部主体。

对于多设备环境,这条线尤其关键。设备 A 可能创建草稿,设备 B 可能解密、修改并保存更新版本,但只要对象仍处于草稿状态,两台设备都不应因为知道未来收件人是谁,就提前扩大解密范围。最终执行发送的客户端必须针对实际提交的最终对象和最终收件人集合完成这一步转换。

真正需要被追踪的因此不是“邮件是否曾经出现在 Drafts”,而是哪个版本最后越过了发送线,哪个客户端发起了该转换,以及转换前后的读取权发生了什么变化。

\Draft、\Drafts 与 $draft 解决的是状态命名,不是承诺政策

现有邮件协议已经拥有成熟的草稿状态语言,但这些机制不能替代 RFC 9787 第 9.5 节的密码学边界。

IMAP4rev2 定义 \Draft 系统标志,可以把消息标记为草稿。RFC 6154 定义 \Drafts 特殊用途邮箱,使客户端与服务器可以识别用于草稿的邮箱。JMAP Mail 则定义 $draft 关键字,用来表示用户把某个 Email 对象视为正在撰写的草稿。

JMAP Mail 的提交示例进一步展示了一个很有价值的状态转换:提交成功时,可以清除 $draft,并把邮件从 Drafts 移到 Sent。这个例子把“仍在撰写”与“已经提交”划分成清楚的存储状态。

但这些状态机制本身并没有定义完整的密码学承诺政策。一个对象带有 \Draft 或 $draft,并不能单独证明它已按 RFC 9787 的建议实施作者专用加密;它也不能证明日常签名密钥没有被调用。类似地,从 Drafts 移到 Sent 可以是很强的操作事件,但它本身不能证明发送前从未给予收件人解密能力。

换言之,邮件存储协议回答“系统把这个对象当作什么”,RFC 9787 第 9.5 节则回答“在这个状态下,谁应该具有什么密码学能力”。两者需要对应,却不能彼此冒充。

有密码学标准,不等于已有草稿专用密钥部署事实

S/MIME 4.0 和 OpenPGP 都提供了邮件密码学所需要的重要机制。它们说明了签名、加密以及相关密钥材料如何工作。然而,从这些协议存在,不能推出跨设备草稿专用密钥已经得到普遍部署。

同样,RFC 9787 规定 SHOULD、MUST 和 MUST NOT,也不能单独证明具体厂商已经按这些要求实现,更不能证明用户环境中的每一个客户端都遵循相同边界。

截至本文研究截止日,RFC Editor 对 RFC 9787 的勘误检索未列出匹配勘误。与此同时,在本文冻结的经审查来源范围内,没有足够证据可以给出部署普及率、厂商合规率或实际草稿泄露发生率,也没有经审查材料足以证明一种已经标准化并广泛部署的跨设备草稿专用密钥交换机制。对法律效力同样不能从这些技术文件外推。

因此,分析必须保持三个层次:RFC 明文规定了什么;从这些规定可以合理推断出什么操作风险;实际产品和部署究竟做了什么。缺少第三层证据时,不能用第一层规范语言替代现实测量。

编辑提案:草稿意图保管收据

为了在多客户端环境中保留这条权限转换的证据,本文提出 Daniel Kade 的“草稿意图保管收据”。这是编辑提案,不是 RFC 9787 的组成部分,也不是 IETF 要求。

它的目标非常窄:不记录邮件本身,而是在草稿对象经过保存、跨设备续写和最终发送时,留下足以回答“谁在什么时候拥有哪种能力”的短记录。

一份收据可以保存草稿对象或版本的内部引用、存储端点类别、当时作者专用加密的范围和密钥类别,并记录哪些客户端在该状态下具有解密或修改能力。跨设备写入发生时,可以留下最后写入者或合并状态。签名部分只需确认该草稿没有使用日常签名密钥签名;这不是声称设备上不存在那把密钥。发送边界之前,还应能够确认没有建立面向收件人的草稿加密。

真正发送时,收据才记录发送事件本身:发起客户端、时间戳、最终收件人集合的摘要以及提交对象哈希。之后只保留必要的发送后清理或墓碑状态,并指出责任人以及复核或到期触发条件。

这种收据不应保存正文、主题、完整收件人列表、私钥、凭证或通用邮箱日志。它的价值来自最小化,而不是把邮箱的全部行为复制到另一个审计系统。

对象哈希也不能被误写成“自动匿名化”。低熵值可能被枚举;跨记录重复使用相同可见值还可能产生关联能力。如果证据本身具有这种风险,更合理的设计可能是使用带密钥的证明方式或受到访问控制的证据,同时限制使用目的,并把保留期压缩到真正需要的范围。

收据最重要的作用不是证明“系统很安全”,而是把三种事实分开:一个版本当时仍是作者内部草稿;哪些受授权客户端能够继续操作它;哪个最终版本真正越过发送边界。没有这三者,跨设备便利很容易把“能够继续写”与“已经对外承诺”混成同一个事件。

来源