密码学 - 域分离

本文深入探讨了密码学中的域分离概念,强调了其在确保数据和操作仅用于特定目的的重要性。文章通过实例分析了域分离的多种类型和应用,包括密钥隔离、AAD区分、以及在哈希函数和签名数据中的应用,以此论证了域分离在防止安全漏洞方面的关键作用,并引用了实际案例和专家观点,强调了在密码学设计中贯彻域分离原则的必要性。

域分离

如果你问密码学家域分离是否重要,他们几乎总会同意它很重要。 甚至已经有几个协议的安全问题,就是因为它缺失了。 在形式化安全证明(或形式化验证)的世界里,研究人员绝对会关注它。

问题在于,当你真正让任何人去定义它的时候。

甚至整理出一个基于它的 的事件清单也很难。 这是因为它对不同的人来说意味着不同的东西,并且实际上涵盖了极其广泛的不同构造、问题和缓解措施。 发生了很多问题,但通常认为它们是更具体的情况。

那么,什么是“域分离”? 我个人的定义是:

域分离是确保事物只能用于特定的预期目的。

(“事物”是什么?数据、函数、密钥等)

类比来说,它非常类似于编程语言中严格的(运行时)类型安全。 它通过使大量的理论问题变得不可能来保护你。 (这就是为什么字节数组对于大多数非超低级的东西来说是一种可怕的数据类型。AES-GCM 密钥、ChaCha20/Poly1305 密钥、UTF-8 编码的字符串和 MPEG4 视频都是不同的东西。尽管它们都只是字节,但很少有方法应该接受超过其中一个。)

使用域分离的事物

虽然域分离作为一个概念几乎可以用于任何事物,但在一些原语中,你会更常见地看到(和需要)它:

  • 随机预言机 / 哈希函数: 这些是许多其他密码学结构的基础构建块,如果你在协议的不同部分使用相同的哈希函数,有时协议的公共部分可能会泄露关于秘密部分的有用状态。 分离你的域:NIST PQC KEMs,预言机克隆和只读不可区分性中描述了完全相同的问题,Bellare 等人利用此问题破坏了一堆 PQ-KEM 提交。 该论文是关于如何使用域分离从单个随机预言机创建多个随机预言机(包含安全证明)的出色参考。
  • 密文: 如果两个不同的系统加密密文时没有进行域分离,那么攻击者可以从一个系统获取密文并将其交给另一个系统(这可能会误解它)。 我亲身经历过一个系统,它使用相同的密钥来加密重定向流程中的受信任 URL 和不同流程中的客户数据。 存在一种攻击,有人可以加密看起来像 URL 的数据,然后导致系统重定向到恶意站点。
  • 签名数据: 与加密数据相同的问题
  • 身份验证流程: 身份验证流程上的反射攻击可以被认为是域分离的一种情况,其中域是发起者/响应者。

域分离的类型

不同的密钥

如果你在做两件不同的事情,你应该使用两个不同的密钥。 (它们可能来源于单个源。) 仅凭这一点就可以保护你免受很多事情的侵害。

例子:

  • TLS 对每个方向的流量使用不同的密钥。 这意味着攻击者不能简单地将流量反射回发送者并使他们接受它。
  • 我设计了多个系统,其中不同类型的数据由不同的密钥加密。 即使同一个系统可以访问所有密钥,这也有帮助。

不同的 AAD

假设加密器和解密器正确设置 AAD 以明确包含域,这也可以工作。

  • 我设计了使用相同 AES-GCM 密钥的协议,但在两个方向上,AAD 的第一个字符指定方向。 (例如:“C”表示由客户端发送,“S”表示由服务器发送。)
  • Web 服务器可以使用单个 AES-GCM 来加密 cookie 和发送给客户端的其他状态。 为了确保没有任何东西可以被交换,数据类型(cookie/表单字段/等)和一个名称都包含在 AAD 中。

一般来说,不同的密钥是比不同的 AAD 更好的解决方案。 你(通常)可以通过使用 KDF 从单个根密钥派生域分离的密钥来接近两全其美。 这也为 AAD 留下了更多标准用法。

包括域作为输入

“不同的 aad”情况实际上只是这种情况的一个特例。 与此类似,这要求为每个域分配一个明确的唯一字符串。 这通常比看起来更难,但是有一种简单、常见的案例。 如果你从一开始就只有有限数量的已知域,你可以只为每个域分配一个唯一的名称,长度相同。 至关重要的是,所有名称的长度都相等,以避免规范化混乱。 (从技术上讲,所需要的是结果数据是单射的,但很难做到正确。 使它们都具有相同的长度是完成此操作的一种简单方法。 另一种方法是具有所有名称的指定终端元素。 这是咨询专家是一个好主意的地方之一。)

这种模式的一个优点是,它可以应用于许多不同的算法,否则这些算法将难以分离:

  • 你可以将域分隔符前置到要签名的数据中。SLH-DSA(FIPS 205,基于 SPHINCS<sup>+</sup>)使用单个字节值来指示签名数据是否已被预哈希。
  • 你可以将域分隔符前置到你的明文中。
  • 你可以将域分隔符与你要哈希的数据一起包含。HPKE 和 SHL-DSA 在整个过程中都这样做。ML-DSA 在派生密钥时包含参数,以便在那里提供分离。
  • 你可以包含一个恒定长度的尾随值。 ML-KEM 对算法参数执行此操作,以实现其密钥派生的域分离。
  • Comparse 提供了关于如何安全地序列化数据的一个不错的说明。

长度分离

警告:这很难做好

如果每个域只处理唯一长度的数据,以便你可以仅从数据的长度来明确识别该域,那么这可能就足够分离了。

数据格式分离

警告:这可能极其难做好

如果绝对不可能将来自一个域的数据误解为来自另一个域的数据,那么你就实现了分离。 (长度分离只是这种情况的一个特例。) 不幸的是,这极其难做好。 许多不同的数据格式可以共存于单个文件中(有时称为多语言文件)。 即使你有一个具有不同内容的单一数据类型,不同的解析器也可能会提取不同的字段。 (考虑一个具有重复键名的无效 JSON 对象。 一些解析器可能会使用第一个值,一些会使用最后一个值,其他的可能会连接。)

在某些方面,包括作为输入策略是这种情况的一个特例。

Comparse 提供了关于如何安全地序列化数据的一个不错的说明。

教育性例子

  • HPKE 在域分离方面做得非常好。 这就是为什么 LabeledExtractLabeledExpand 都存在的原因。
  • 总的来说,SPHINCS+ 在域分离方面做得很好。 它是一种基于哈希的签名方案,因此在不同的上下文中哈希大量数据。 大多数时候,它在被哈希的数据中包含一个“地址”,以便哈希函数的每次使用都是不同的。 不幸的是,设计人员有一次忘记包含这种分离(当他们直接使用一些数据而没有首先进行哈希时),这导致了攻击。 虽然这没有被描述为“域分离”缺陷,但我认为它是一个,因为它与我们在其他地方看到的模式相匹配。
  • ML-KEM (FIPS 203 / Kyber) 由于公众评论,在发布之前添加了域分离到其密钥派生算法。 担心的是,有人可能会(错误地)将相同的(种子)密钥与多个算法(或具有 ML-KEM 的参数集)一起使用,并在它们应该完全分离时获得相关的密钥。 通过包含域分离,ML-KEM 确保不同的算法将始终派生不相关的加密密钥。

最后思考

在密码学设计中很少考虑适当的域分离,并且只是在过去几年中,我们才看到人们积极地关心它。 许多(大多数?)研究论文只是假设你可以明确地连接数据并再次解析出来。 许多 AAD 和其他结构只是连接数据,而没有意识到这不起作用。 我甚至看到密码学家完全否定数据序列化,认为它“不是密码学”并且不值得他们花时间。 (在这种情况下,有人想要签署一个复杂的数据,而学术密码学家拒绝审查数据如何转换为实际的签名字节。)

我真的相信域分离(及其伙伴规范化)是可以将许多不同的特定实例映射到其上的安全问题的类别。 (这与“注入”攻击是一个庞大的攻击家族的方式非常相似。) 即使我们由于缺乏域分离而没有看到对我们系统的任何攻击,我们也必须包含这些安全措施。 我从来没有见过有设计师后悔额外的域分离的情况,而互联网上充斥着因忽略它而导致漏洞。

我在这里留下一段我的朋友 str4d 的引言

其中一个关键要点:确保域分离无处不在!它可以消除整个类别的错误🐛

  • 原文链接: github.com/SalusaSecondu...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
SalusaSecondus
SalusaSecondus
江湖只有他的大名,没有他的介绍。