假设有人有我的加密数据,他想解密它。人们总是谈论密钥的长度(例如 256 位)如何决定加密的熵,这完全有道理。如果攻击者尝试所有 2 256种可能性,他的曾曾-曾-...-孙子将拥有我的数据。
但是,如果他多年来一直使用错误的算法怎么办?算法本身的选择不是也增加了熵,还是我错误地假设了这一点?因此,super_secret.aes256
我不会命名我的文件,而是只命名它,super_secret.rsa256
或者甚至根本不给它一个文件结尾?
假设有人有我的加密数据,他想解密它。人们总是谈论密钥的长度(例如 256 位)如何决定加密的熵,这完全有道理。如果攻击者尝试所有 2 256种可能性,他的曾曾-曾-...-孙子将拥有我的数据。
但是,如果他多年来一直使用错误的算法怎么办?算法本身的选择不是也增加了熵,还是我错误地假设了这一点?因此,super_secret.aes256
我不会命名我的文件,而是只命名它,super_secret.rsa256
或者甚至根本不给它一个文件结尾?
如果您正在设计密码系统,答案是否定的。Kerckhoffs 的原则指出“密码系统应该是安全的,即使系统的所有内容,除了密钥,都是公共知识。” 重申为香农的格言,这意味着“一个人应该在假设敌人会立即完全熟悉它们的情况下设计系统。”
假设攻击者不会学习您的算法是通过 obscurity实现的安全性,这是一种被认为不足的安全性方法。
依靠攻击者不知道算法不会增加他或她的任何工作,因为根据 Kerckhoff 的说法,他或她要么知道,要么可以合理地预期会发现。如果它不增加不确定性,它就不会增加熵。他们的能力不是你可以量化的。
在丢失密码系统的情况下,就像您描述的那样,通常有足够的历史或统计信息来确定算法的性质(如果不是密钥本身)。但是您不能在假设它将是一用就丢了。那是 OpSec,而不是密码学。
编辑评论提到使用算法选择作为关键的一部分。这种方法的问题是算法选择必须在数据解密之前确定。这正是当今 TLS 等协议的工作方式。
如果您真的希望将算法混合在一起并使用关键因素来确定诸如 S-box 选择之类的事情,那么您实际上是在创建一个单一的新算法(采用所有众所周知的风险来滚动您自己的算法需要。)如果您创建了一个新算法,那么密钥的所有位都是该熵计算的一部分。但是,如果您可以指出确定算法而不是密钥材料的特定位,您仍然必须将它们视为协议位并排除它们。
关于算法的保密性,您的协议今天可能是保密的,但如果您的一个代理被发现并且他的系统被复制,即使没有密钥被泄露,旧消息也不再使用保密算法。您可能归因于它们的任何“熵”都丢失了,您甚至可能都不知道。
实际上,不,正如约翰的回答巧妙地解释的那样。
假设您有足够的安全加密方法可供选择,您可能会随机选择一种方法并使用它来加密数据,例如使用 256 位密钥。所用算法的选择需要“添加”到密钥中,并成为“不被泄露的秘密”的一部分(如果有八种加密算法可供选择,则将组合熵设为 259 位)。
这样做的问题包括:
仅添加了少量位:八种算法仅添加了三位熵。添加 8 位(对于 256 位密钥总共 264 位)将需要 256 种不同的加密算法。几乎可以肯定,找到足够的安全算法来产生实际影响比简单地扩展单个攻击者已知的算法的密钥长度要困难得多。
您必须通过选择算法来“扩展”密钥:这意味着将选择传递给“用户”,以便与普通密钥一起“记住”。这极大地复杂了密钥管理的过程。将选择存储在加密数据中是不可能的,因为具有“全部知识”的攻击者将能够找到信息并知道要使用哪种算法。
如果选择的任何算法留下某种“指纹”,允许攻击者识别所使用的算法(或至少减少可能算法的范围),那么这将(部分)消除额外的熵位。
总而言之,扩展所用密钥的长度要容易得多,而且不必担心攻击者知道加密方法。
@John Deter 和 @TripeHound 的答案很好地解释了事情,但我想举一个例子,将 Kerckhoffs 的原则放在上下文中。从外部攻击者的角度来处理这些问题是很自然的,但这并不是唯一相关的威胁模型。事实上,大约一半的数据泄露都是从内部代理(也就是员工、承包商等)开始的,其中既有意外泄露,也有故意泄露。
如果外部攻击者无法轻易推断出您使用的系统,则拥有隐藏的加密算法可能有助于抵御外部攻击者。但是,对于有权访问您的代码的内部攻击者,它绝对没有提供额外的保护。举个极端的例子,如果您的系统在您的数据库中保留了关键的个人身份信息 (PII),但生产数据库访问凭证、加密算法和加密密钥都直接存储在您的代码存储库中,那么您实际上已经为所有有权访问的人提供了访问您的所有客户的 PII 的代码存储库。
当然,您不想这样做,因此您将生产系统与所有人(期望管理员)隔离开来,将加密密钥存储在单独的密钥管理系统中(尽可能)只有应用程序可以访问,等等......您的开发人员知道使用了哪些加密算法(因为他们可以在代码存储库中看到它),但他们无权访问生产数据库,即使他们确实获得了对数据库的读取权限,他们也没有密钥解密那里的数据。
这就是 Kerckhoffs 原则的全部要点——你唯一需要保密的是实际的秘密(也就是你的加密密钥)。每个人都可以知道其他所有内容,并且您仍然很安全。这很好,因为只保守一个秘密就够难了。试图设计一个不仅隐藏密钥而且隐藏加密算法和其他细节的系统,让尽可能多的人知道是相当困难的,而且更容易失败。
简而言之,人们不善于保守秘密。因此,设计您的系统以减少需要保留的秘密实际上会让您更加安全,即使这看起来违反直觉。毕竟,您的建议在某种程度上是有道理的:为什么我们应该只加密我们的数据?让我们也隐藏加密方法并更加安全! 但在实践中,隐藏更多的东西会给你更多的犯错空间和虚假的安全感。最好使用一种有效的加密方法,使保密尽可能简单 - 隐藏密钥并且消息是安全的。
抽象地说,如果有 2^n 个加密方案同样难以破解,并且具有相同的可能密钥空间,那么当然,您可以将新的加密方案定义为“随机选择这 2^n 个方案中的一个”并且有效地考虑将那些 n 位添加到密钥中。
但在实践中,即使这是可能的,这也是很多不必要的复杂性,因为您可以只选择一个算法并使密钥更长一点。