【问题标题】:DCPcrypt encryption and hash algorithm used使用的 DCPcrypt 加密和哈希算法
【发布时间】:2012-11-27 08:39:06
【问题描述】:

我正在使用 Delphi 2007 中的 DCPcrypt 库为内部应用程序加密文本。

我目前正在使用以下代码(不是我的实际密钥):

  Cipher := TDCP_rijndael.Create(nil);
  try
    Cipher.InitStr('5t@ck0v3rf10w', TDCP_md5);
    Result := Cipher.EncryptString('Test string');
  finally
    Cipher.Burn;
    Cipher.Free;
  end;

InitStr 的注释是:

根据密钥字符串的哈希进行密钥设置

将 MD5 算法换成 SHA2-256 或 SHA2-512 是否会对加密强度产生任何理论上或实际的差异?

【问题讨论】:

    标签: delphi encryption hash cryptography


    【解决方案1】:

    您应该指定加密的攻击类型;假设使用known-plaintext attack,并且入侵者使用预先计算的哈希值来查找密钥字符串 - 那么所使用的哈希算法之间应该没有区别,任何哈希算法都需要几乎相同的时间来查找密钥字符串。

    【讨论】:

      【解决方案2】:

      您的问题的直接答案是“否” - 它不会对加密强度产生任何明显的影响。是的,MD5 被破坏了,但实际上它的弱点在这个特定的应用程序中没有任何区别。 AES 的密钥大小为 128、192 和 256 位。您在这里所做的只是为密钥创建一个字符串假名(可以是 16 字节、24 字节或 32 字节)。当密码学专家说散列函数是broken 时,他们的意思是,给定一个已知的散列输出,计算与原始消息不同的消息是可行的,原始消息也散列到相同的输出。换句话说,为了使哈希函数的加密强度或弱点具有任何意义,二进制密钥必须已经为恶意方所知,这意味着它只有在您的安全性已经完全被破坏时才有意义。

      散列算法的强度与非对称密码的强度完全无关。

      然而……

      但是,更严重的问题是您的代码中没有加盐。除非您打算手动加盐(不太可能),否则您的通信很容易受到重放攻击。如果您使用 ECB 模式,这将变得更糟,但如果不加盐,这对于任何模式都是一个主要的安全问题。 “加盐”是指在加密之前在 IV 或消息的头部注入足够大的不可预测的非重复值。

      这凸显了 DCPCrypt 的一个巨大问题。大多数 DCPcrypt 用户对密码学的了解不足,无法理解正确加盐的重要性,并且会以您所拥有的方式使用密码组件。当您以这种方式使用 DCPcrypt(这很自然)时,DCPcrypt 会NOT加盐。事实上,它将 IV 设置为零。而且情况变得更糟...如果您选择了一种密钥流类型的链接模式(非常流行),并且您的 IV 习惯性为零,那么如果已知或猜到一条纯文本消息,您的安全性将完全被破坏, (或者只是猜测消息的一部分)。 DCPcrypt 确实提供了另一种方法来初始化二进制密钥(不是从字符串),同时允许用户设置 IV(您必须自己生成一个随机 IV)。下一个问题是整个静脉注射管理变得有点复杂。

      披露

      我是TurboPower LockBox 3的作者。 Dave Barton 的 DCPcrypt 是一部令人钦佩的综合性工程作品,是我编写 LockBox 3 的灵感之一。

      【讨论】:

      • 感谢salt的提醒,我在hash时总是salt,但我很少做加密,我忽略了它!你会这样做:Result := Cipher.EncryptString(my_salt + 'Test string');?
      • 是的条件:(1) my_salt 是一个随机数(每条消息发出); (2) my_salt 至少有 64 位熵(越多越好); (3) 您需要在侧通道上传输 my_salt; (4) 不要使用欧洲央行。尽管您可以通过这种方式安全地进行操作,但更传统的技术是给 IV 加盐。
      • 感谢您的出色回答,默认密码模式是 CBC(我需要了解不同的模式)。我怎么知道我的盐有多少熵?我假设 IV 是传递给 InitStr 的密钥?如果其中任何一个答案很复杂,我会提出另一个问题。
      • 如果你的 PRGN 很好,并且基于 64 位种子,你只需生成一个随机的 8 个字节就可以获得 64 位熵。内置的 Delphi PRGN 永远不会有超过 32 位的熵。 IV与钥匙完全不同。我目前没有打开代码,但我记得有一个名为 SetIV() 的方法来设置它。当然,如果你调用它,你就不能调用 InitStr(),因为这会破坏 IV。
      猜你喜欢
      • 2014-12-13
      • 1970-01-01
      • 2011-10-10
      • 2011-06-24
      • 2012-01-27
      • 1970-01-01
      相关资源
      最近更新 更多