本文深入探讨了密码学中的域分离概念,强调了其在确保数据和操作仅用于特定目的的重要性。文章通过实例分析了域分离的多种类型和应用,包括密钥隔离、AAD区分、以及在哈希函数和签名数据中的应用,以此论证了域分离在防止安全漏洞方面的关键作用,并引用了实际案例和专家观点,强调了在密码学设计中贯彻域分离原则的必要性。
如果你问密码学家域分离是否重要,他们几乎总会同意它很重要。 甚至已经有几个协议的安全问题,就是因为它缺失了。 在形式化安全证明(或形式化验证)的世界里,研究人员绝对会关注它。
问题在于,当你真正让任何人去定义它的时候。
甚至整理出一个基于它的 好 的事件清单也很难。 这是因为它对不同的人来说意味着不同的东西,并且实际上涵盖了极其广泛的不同构造、问题和缓解措施。 发生了很多问题,但通常认为它们是更具体的情况。
那么,什么是“域分离”? 我个人的定义是:
域分离是确保事物只能用于特定的预期目的。
(“事物”是什么?数据、函数、密钥等)
类比来说,它非常类似于编程语言中严格的(运行时)类型安全。 它通过使大量的理论问题变得不可能来保护你。 (这就是为什么字节数组对于大多数非超低级的东西来说是一种可怕的数据类型。AES-GCM 密钥、ChaCha20/Poly1305 密钥、UTF-8 编码的字符串和 MPEG4 视频都是不同的东西。尽管它们都只是字节,但很少有方法应该接受超过其中一个。)
虽然域分离作为一个概念几乎可以用于任何事物,但在一些原语中,你会更常见地看到(和需要)它:
如果你在做两件不同的事情,你应该使用两个不同的密钥。 (它们可能来源于单个源。) 仅凭这一点就可以保护你免受很多事情的侵害。
例子:
假设加密器和解密器正确设置 AAD 以明确包含域,这也可以工作。
一般来说,不同的密钥是比不同的 AAD 更好的解决方案。 你(通常)可以通过使用 KDF 从单个根密钥派生域分离的密钥来接近两全其美。 这也为 AAD 留下了更多标准用法。
“不同的 aad”情况实际上只是这种情况的一个特例。 与此类似,这要求为每个域分配一个明确的唯一字符串。 这通常比看起来更难,但是有一种简单、常见的案例。 如果你从一开始就只有有限数量的已知域,你可以只为每个域分配一个唯一的名称,长度相同。 至关重要的是,所有名称的长度都相等,以避免规范化混乱。 (从技术上讲,所需要的是结果数据是单射的,但很难做到正确。 使它们都具有相同的长度是完成此操作的一种简单方法。 另一种方法是具有所有名称的指定终端元素。 这是咨询专家是一个好主意的地方之一。)
这种模式的一个优点是,它可以应用于许多不同的算法,否则这些算法将难以分离:
警告:这很难做好
如果每个域只处理唯一长度的数据,以便你可以仅从数据的长度来明确识别该域,那么这可能就足够分离了。
警告:这可能极其难做好
如果绝对不可能将来自一个域的数据误解为来自另一个域的数据,那么你就实现了分离。 (长度分离只是这种情况的一个特例。) 不幸的是,这极其难做好。 许多不同的数据格式可以共存于单个文件中(有时称为多语言文件)。 即使你有一个具有不同内容的单一数据类型,不同的解析器也可能会提取不同的字段。 (考虑一个具有重复键名的无效 JSON 对象。 一些解析器可能会使用第一个值,一些会使用最后一个值,其他的可能会连接。)
在某些方面,包括作为输入策略是这种情况的一个特例。
Comparse 提供了关于如何安全地序列化数据的一个不错的说明。
LabeledExtract
和 LabeledExpand
都存在的原因。在密码学设计中很少考虑适当的域分离,并且只是在过去几年中,我们才看到人们积极地关心它。 许多(大多数?)研究论文只是假设你可以明确地连接数据并再次解析出来。 许多 AAD 和其他结构只是连接数据,而没有意识到这不起作用。 我甚至看到密码学家完全否定数据序列化,认为它“不是密码学”并且不值得他们花时间。 (在这种情况下,有人想要签署一个复杂的数据,而学术密码学家拒绝审查数据如何转换为实际的签名字节。)
我真的相信域分离(及其伙伴规范化)是可以将许多不同的特定实例映射到其上的安全问题的类别。 (这与“注入”攻击是一个庞大的攻击家族的方式非常相似。) 即使我们由于缺乏域分离而没有看到对我们系统的任何攻击,我们也必须包含这些安全措施。 我从来没有见过有设计师后悔额外的域分离的情况,而互联网上充斥着因忽略它而导致漏洞。
我在这里留下一段我的朋友 str4d 的引言。
其中一个关键要点:确保域分离无处不在!它可以消除整个类别的错误🐛
- 原文链接: github.com/SalusaSecondu...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!