【问题标题】:Why can I encrypt data with one DES key and successfully decrypt with another?为什么我可以用一个 DES 密钥加密数据并用另一个成功解密?
【发布时间】:2014-04-22 09:53:56
【问题描述】:

我尝试使用 pyDes 和 Crypto.Cipher.DES 模块来实现 DES 算法。我发现一个问题,当我用82514145 密钥加密然后用93505044 解密密码时,我可以检索解密的文本。我发现 256 个键的行为是这样的。这是违反密码学的。我的代码如下:

    from Crypto.Cipher import DES
    plain_text = 'asdfghij'
    print 'plain Text: ', plain_text

    des = DES.new('82514145', DES.MODE_ECB)
    cipher_text = des.encrypt(plain_text)
    print 'the cipher text is ', cipher_text

    des = DES.new('93505044', DES.MODE_ECB)
    print 'the decrypted text is: ', des.decrypt(cipher_text)

输出是:

plain Text:  asdfghij

the cipher text is  @�Z����

the decrypted text is:  asdfghij

我的工作有什么错误吗?我也用 pyDes 得到了同样的结果。

【问题讨论】:

  • 在DES的不同分组密码模式中观察到相同的情况

标签: python cryptography des encryption-symmetric pycrypto


【解决方案1】:

DES 密钥只有 56 位长,但由于奇偶校验位,它们被扩展为 64 位。每个字节的第八位应设置为确保odd parity

许多加密库忽略奇偶校验位,这意味着有多种方法可以在 64 位密钥字符串中表示相同的 56 位密钥。事实上,有 28 种不同的方式,这就解释了为什么您会找到 256 个匹配键。

您的示例包括两个仅在奇偶校验位上不同的键值。见下文 - 奇偶校验位在 []:

82514145 
= 0x3832353134313435 
= 0011100[0] 0011001[0] 0011010[1] 0011000[1] 0011010[0] 0011000[1] 0011010[0] 0000000[0]

93505044 
= 0x3933353035303434 
= 0011100[1] 0011001[1] 0011010[1] 0011000[0] 0011010[1] 0011000[0] 0011010[0] 0000000[0]

这两个密钥实际上都不是真正有效的。该密钥的正确表示是:0x3832343134313401

【讨论】:

  • 非常感谢您让我清楚这些键实际上对应于唯一键...
  • 你能帮我弄清楚openssl库如何处理这256个匹配密钥映射到相应唯一密码的8字节密钥吗?在此先感谢:)
  • @ceasif 如果您有新问题,请单独发布。请随意参考此问题以供进一步阅读。也请随时在评论中对我的链接进行 ping 操作,以便我找到它。
【解决方案2】:

这是为什么you should never use a user provided password as a key itself in a key in a cipher 的一个很好的例子。您应该改用key derivation function

此外,您不应将 DES 用于教育以外的目的,因为它通常被认为是不安全的。现在认为密钥太短了,并且有一些已知的攻击可以降低其复杂性。

【讨论】:

  • -1 这不是为什么使用密码作为密钥不好的例子。首先,在代码示例中没有直接将密码用作密钥的迹象。其次,这不是问题的原因——被忽略的奇偶校验位是原因。你关于密钥长度的观点和关于密码的一般观察是非常有效的。
  • @Duncan DES.new 使用 82514145 作为原始二进制密钥创建一个新的密码实例。 82514145 是否是“密码”是有争议的,但 KDF 解决的主要问题之一是 avoiding predictable patterns in the key that may interfere with the expected behavior of the cipher,在我看来,正如您在回答中所记录的那样,这就是正在发生的事情。
  • 我们不知道键值来自哪里,所以我们不能假设它是密码。使用 KDF 将从密码中生成好的密钥,但它们将是完全随机的,并且如果它们仅在奇偶校验位上有所不同,它们仍然会表现出我在回答中解释的相同行为。
  • @Duncan 注意我并不是说它是一个密码——只是示例密钥展示了模式,并且使用 KDF 使得此类问题的可能性大大降低。找到两个表现出这种行为的 ascii printable 键是微不足道的,但是当它们通过 KDF 运行时要做到这一点要困难得多。我当然同意您的回答最适合提出的问题,但我认为这些信息仍然值得一提。
  • 啊,我明白了。你是从通过尝试不同的密钥/密码来颠覆系统的角度来看待这个问题的。这更有意义!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-19
  • 2018-10-14
  • 1970-01-01
相关资源
最近更新 更多