ccrypt 'AES 256' 文件加密是否存在根本缺陷

信息安全 AES 文件加密
2021-09-06 11:55:58

unix/linux 实用程序 ccrypt 声称是旧的 unix crypt 的更安全的替代品。然而,在我看来,它有一个根本性的缺陷。

当您使用 ccrypt 加密文件时,它会使用您提供的密码来创建一个随机的 256 位密钥以用于 AES。要再次解密您提供密码的文件,ccrypt 使用密码获取 AES 密钥并解密文件。

好的,该文件是使用 256 位 AES 安全加密的,但其安全性完全取决于密钥的安全性——而密钥并不安全。

解密时 ccrypt 实际上会告诉您用于解密密钥的密码是否正确,并且如果您提供错误的密钥,则不会尝试解密。因此,当您猜对时,暴力破解密钥会告诉您,这将是微不足道的。

这个问题适用于使用这种方法的任何文件加密,重要的是密钥的安全性,用于编码实际数据的算法几乎无关紧要。

消息等被加密以保护它们,而在传输过程中基于密钥的加密是有意义的,但“固定”文件加密是不同的。即使是单独保存密钥的 GPG 文件加密也无济于事,通常很明显 GPG 已被使用并且密钥保存在“众所周知”的地方。同样重要的是关键安全性,文件加密无关紧要。

好的,可以通过将密钥放在 USB 记忆棒或其他东西上来完全分离密钥,但对于大多数文件加密来说,这有点 OTT 并且无论如何丢失记忆棒都意味着丢失一个人的数据。文件是通常需要长期保存的东西,密钥需要与文件一起备份。

我认为对于简单的文件加密,旧的基于 DES 的加密更好。蛮力强制它要困难得多。

我完全错了吗?:-)

2个回答

基于密码的加密本质上容易受到字典攻击。实际上,当您拥有加密文件时,您始终可以尝试使用给定密码对其(或其中的一部分)进行解密,并查看结果是否有意义。因此,可以得到加密文件的攻击者(我们假设这是可能的,因为否则加密没有意义),可以在他自己的机器上“尝试密码”,直到找到匹配项。需要注意的是,对于“结果是否有意义”部分,攻击者并不需要100%可靠的测试:如果攻击者的测试足以拒绝99.9999%的错误密码,那么他仍然会减少他的密码列表来复查增加了一百万倍。

诸如ccrypt 之类的工具提供了拒绝错误密码的测试并不能改变这一事实。当然,攻击者也可以使用该测试,但这不会给他带来太多额外的优势。攻击者在没有该测试的情况下已经可以轻松工作,因为现实生活中的数据具有很多结构(大多数文件格式具有非常容易识别的标题),如果攻击者有兴趣破解密码,那么数据必须是有价值的,因此“真实-生活”。

有两种方法可以使基于密码的加密更强;它们是累积的,你应该同时使用它们。第一种方法是使用强密码,这意味着其中包含大量随机性的密码(像往常一样,有关该主题的讨论,请参阅此问题)。第二种方法是使用良好、正确配置的密码散列函数将密码转换为加密密钥那里的“正确配置”意味着将使用盐来防止并行攻击(当有多个具有不同密码的加密文件,并且攻击者想要破解其中的一个或多个时),并且密码哈希函数被制作通过多次迭代故意增加成本以使字典攻击更难。

在后一点上,ccrypt 似乎有缺陷。它使用常见问题解答描述的内容对密码进行哈希处理:

Ccrypt 使用基于 AES 的散列算法(即基于 Rijndael 块密码)。它不是 SHA1 等标准哈希算法之一。因此,对于您的应用程序,您应该没问题。从安全的角度来看,使用哪种散列算法并不重要,只要它是无冲突的即可。

这不是好兆头。首先,用作者自己的话来说,这是一个自定义的自制函数,这绝不是一个好兆头。而且作者讲了需要“无冲突”的功能,这与基于密码的密钥推导完全无关,因此对这类事情的要求把握得比较差;这也不是一个好兆头,尤其是与自制功能结合使用时。

查看源代码(这是开源的好处:您可以自己查看作者认为不适合记录的内容),自定义哈希似乎以下列方式工作:

  • KH都设置为 32 字节值 0x00 的序列。
  • 对于每个密码字符c(单个字节;我们在这里使用与 ASCII 兼容的编码,例如 UTF-8),请执行以下操作:
    • 将K的每个字节c异或。
    • 用密钥K和块大小 256 位的Rijndael将H替换为H的加密。
  • H的最终值是“散列密码”。

这需要以下评论:

  • 常见问题解答说“AES”,但它不是 AES。AES是一个包含三个函数的家族,它是被称为 Rijndael 的函数家族的一个子集。AES 始终使用 128 位块;在这里,Rijndael 与 256 位块一起使用,因此它不是 AES stricto sensu

  • 作为散列函数,它很烂。该过程基本上归结为重复加密单个块,每次使用 256 个可能的密钥中的一个(每个加密密钥的 32 个字节始终彼此相同)。由于这是对称加密,因此对称解密也有效,这允许中间相遇攻击。基本上,输出大小为 256 位,但原像电阻最多为 2 128,而不是 2 256虽然这不是密码散列的直接问题,但它仍然证明了自定义方案的根本缺陷。

  • 作为密码散列函数,它很臭。它不仅是无盐的,而且速度也非常快。具有基本 PC 的攻击者将使用AES-NI指令在几十个时钟周期内计算 Rijndael 加密(AES-NI 指令旨在专门支持 AES,但它们仍可用于有效地支持256 位块;见本文第 2.1 节)。此外,由于密码字节是逐个处理的,因此可以在连续的密码试验之间分担大量计算成本:从哈希密码“foo”到“fooA”、“fooB”、“fooC”的哈希值。 .. 可以使用每个 Rijndael-256 调用来计算。

    可以估计,一台廉价的现成 PC每秒能够散列至少 1亿个潜在密码。很少有人选择的密码能抵抗这样的冲击,充其量只能超过几分钟。就密码散列而言,这是非常糟糕的。


总结: ccrypt对字典攻击的抵抗力弱,但这并不是因为它对密码的正确性进行了测试。它很弱,因为它的密码散列程序是一种自制的结构,它积累了使字典攻击非常有效的缺陷。使用正确配置的密码散列函数(例如bcrypt),它实际上可以增强一百万倍(迭代计数将被调整,以便 PC 每秒只能散列 100 个密码,而不是 1 亿;它仍然是高度使用,因为 1/100 秒对人类而言并不是很大的延迟)。

原来的答复解释说ccrypt不使用盐,不使用真实的AES,不使用标准的KDF:https://www.mathstat.dal.ca/~selinger/downloads/ccrypt-answer.txt


我是 ccrypt 的作者。很抱歉这么晚才回复这个帖子,但我最近才知道。与往常一样,有关 ccrypt 的问题也可以在 SourceForge 上的 ccrypt 论坛中直接向我提出(并且可能会收到更快的回复)。

为了解决最初的问题:让我明确指出,ccrypt 以及所有其他基于密码的加密程序都受到暴力攻击,包括字典攻击。正如 Thomas Pornin 恰当地指出的那样,“基于密码的加密天生就容易受到字典攻击”。没有什么可以阻止攻击者尝试所有可能的密码。这不是缺陷,而是生活的基本事实,每个密码学用户都必须了解。如果您使用“poodle”等弱密码,攻击者将能够猜出您的密码并解密您的数据。如果您使用诸如“hVztmdz28fNemDZnxj5YLjXz”之类的强密码,就目前所知,您的数据在可预见的未来将保持安全。

我想澄清原始海报以及答案和评论中提出的其他几点。

在原始帖子中,似乎对 ccrypt 的替代品存在误解。这可能是因为我很久没有更新文档的那部分了。当我(在 2001 年)写到 ccrypt 是旧的 unix crypt 程序的替代品时,我指的是 crypt(1) 程序,而不是 crypt(3) 库函数。Crypt(1) 是一个基于密码的文件加密程序,至少自 1979 年以来就存在于 Unix 中(它在第 7 版中:http : //man.cat-v.org/unix_7th/1/crypt),并在 1980 年代和 1990 年代广为人知。它使用了一种基于 Enigma 密码的弱算法,该算法在二战中已经被破解。另一方面,crypt(3) 是一个库函数,可将密码散列为 /etc/password 中使用的格式。据我所知,crypt(3) 并没有什么特别的问题,它至今仍在使用。Ccrypt(1) 是 crypt(1) 的替代品,而不是 crypt(3) 的替代品。询问 ccrypt 是否比 crypt(3) “更好”是没有意义的,因为它们做的事情完全不同。考虑到今天没有人记得 crypt(1) 程序,我可能应该更新文档的那部分。

原帖还提出了一个问题,即 ccrypt 会在用户输入错误密码时通知用户,以及这是否会使字典攻击更快。答案是这不会使字典攻击更快,除非可能是一个非常小的常数因子。托马斯已经在他的回答中很好地解释了这一点,但为了强调这一点,请考虑这一点:假设加密文件是 JPEG 文件。每个 JPEG 文件都以相同的 3 个字节开头,即 ff d8 ff。因此,已经有一个非常简单的测试来检查您的密钥的可能正确性:只需解密第一个块并检查文件是否以 ff d8 ff 开头。大多数其他文件格式也包含这种类型的已知纯文本,例如,每个 PDF 文件都以“%PDF”开头。检查文件是否为纯文本文件也很容易。因此,ccrypt 提供密码匹配功能这一事实并没有使攻击变得更容易。事实上,ccrypt 对“匹配”密钥的检查也不是 100% 准确的。任何随机密钥都有 40 亿分之一的机会通过测试,即使它不是正确的密钥。该功能的存在是为了防止人们意外地用错误的密钥解密文件(从而用垃圾覆盖其中的所有数据)。

总结:与所有基于密码的加密软件一样,ccrypt 也容易受到字典攻击。用户必须意识到这一点并选择强密码。然而,正如所建议的那样,通过将这些攻击的成本增加一个常数因素来使不安全的密码稍微不安全会适得其反。相反,唯一正确的响应是首先使用安全密码。Thomas Pornin 的答案中提出的大部分剩余分析都是有缺陷的,并且没有发现 ccrypt 的实际弱点。