【问题标题】:Making AES decryption fail if invalid password如果密码无效,则使 AES 解密失败
【发布时间】:2013-02-05 23:25:22
【问题描述】:

我最近使用 PyCrypto 在一个项目中使用 AES 编写了自己的加密方法。我使用哈希生成一个 32 字节的密码,并使用 CBC 将其提供给 AES-256 位加密。文件输入使用 PKCS#7 填充以符合可被 16 整除的要求。

我可以毫无意外地对文件进行加密和解密,并且最初与输出文件一起加密的输入文件具有相同的 SHA-256 哈希值。

我发现的唯一问题是,如果我提供了错误密码,解密仍然会发生。这是我正在做的事情的一个问题,因为如果密码错误,我需要快速解密失败。

我怎样才能做到这一点?我听说过其他 AES 加密方法,但 PyCrypto 似乎只支持 ECB、CBC、CFB、OFB、CTR 和 OpenPGP。如何实现加密的强 AES,如果没有正确的密码,解密将失败?

【问题讨论】:

  • I've written my own encryption method -- 那是你的问题。
  • 加密方法不是我自己写的。我编写了一个使用 AES 作为加密方法的程序。我没有那么愚蠢。
  • AES 只是一个原语(分组密码)。我知道我的“加密方法”是指一种将这个原语(和其他)用于更高级别目的(基于密码的任意数量数据的加密)的方法。这就是我的意思:这仍然是您可能不应该自己做的事情。
  • 您能否推荐一种安全的加密方法,它提供 256 位加密,使用强而慢的哈希方法作为密钥,并且可以在不知道文件全长的情况下进行加密?如果有一个满足我所有要求的即插即用解决方案,那将是太棒了
  • 我很确定有现有的解决方案,但我不是专家。至少对于散列部分,有 PBKDF2。专家编写和审查的软件也会定期将流密码应用于任意长度的明文(另一方面,加密人每隔一个月就会提出更复杂的攻击)。至于将两者结合起来,我很难过,但我认为有现有的标准,尽管可能没有开源实现。

标签: python encryption aes


【解决方案1】:

确保密文在更改后不会解密的最佳方法是添加身份验证标签。身份验证标签用于提供密文的身份验证和完整性。

此标签可能由密文上的 MAC(例如 AES-CMAC 或使用 SHA-256 的 HMAC)组成。但是,这需要第二个密钥才能安全。

另一种方法是使用经过身份验证的加密,例如 GCM。 GCM使用单一密钥,生成认证标签(大小可配置)。

确保使用正确生成的 IV。 IV可以作为密文的前缀,在计算认证标签时应该包含),不要忘记你的纯文本的大小可能不会被隐藏。

你应该在解密密文之前验证标签的正确性

请注意,一般情况下,您不应加密密码,除非您以后需要访问准确的密码。对于密码验证,请改用 PBKDF2。

【讨论】:

  • 我正在使用哈希方法作为密码,bcrypt 现在,虽然我可能使用 PBKDF2。不幸的是,Python 中几乎不支持经过身份验证的 AES 模式。我对 MACing 密文几乎一无所知,关于从哪里开始有什么想法吗?我想使用一些对我有用的东西,这样我搞砸它和损害安全性的机会就更少了。
  • This article 似乎做了很多正确的事情。带有 SHA256 的 HMAC,两个密钥,HMAC 中的 IV。不能完全保证,但它看起来确实不错......
【解决方案2】:

没有任何关于 AES(或任何其他加密算法)可以让您知道您是否拥有正确的密钥。也就是说,当您真正想在数学领域之外使用密码学时,这是一个非常有用的功能。

您需要做的是在消息的开头添加一个具有已知值的块,这样在解密第一个块后,您可以将其与已知值进行比较,并知道您是否拥有错误的密钥。如果您要加密的数据有一个已知的标头,您可以改用它。

或者,您可以将密钥的加密散列(例如 SHA-256)与消息一起发送,攻击者只有在破解散列的情况下才能恢复密钥。

【讨论】:

  • 我不是加密专家,但如果明文的第一个块是已知值,那么攻击者不能通过查看密文的第一个块(以及 IV ,如果适用,但包含在纯文本中)?
  • 我希望不是,那是known-plaintext attack。如果您非常偏执,您可以将第一个块作为密钥,或者一些不可逆的密钥哈希。
  • @JeffreyHantin 如果密钥具有足够的熵,这不是问题,例如如果它是随机生成的。请注意,这是关于加密密码,而不是使用 密码加密某些内容。
  • 警告:接受的答案使用非标准加密做法。密文上的 MAC 或经过身份验证的加密是接受或拒绝密文的方式。
  • @JeffreyHantin 这或多或少是交叉发布到crypto,没有太多提示,讨论继续在那里。
【解决方案3】:

要提供所需的快速失败属性,您需要在被加密的数据前添加一个标头。我建议使用与已知常数“magic number”连接的随机“混杂因素”nonce(类似于加密salt);混杂因素的存在,就像盐一样,提供了一种针对基于预先计算表的攻击的防御措施。

有了这样的报头,你只需要破译报头并验证幻数字段;如果它与已知常数不匹配,则密钥无效。如果匹配,则丢弃标头并处理输入的其余部分。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-29
    • 2021-11-16
    • 1970-01-01
    • 2020-04-20
    • 1970-01-01
    • 1970-01-01
    • 2016-02-02
    • 2017-10-05
    相关资源
    最近更新 更多