【问题标题】:DES encryption in Java vs .NET - why different?Java 与 .NET 中的 DES 加密 - 为什么不同?
【发布时间】:2011-08-28 19:50:54
【问题描述】:

我有一个对字符串进行 DES 加密的 .NET 方法:

public static string EncryptTripleDES(string value, byte[] encryptionKey, byte[] initializationVector) {
  if (!value.IsNullOrEmpty()) {
    TripleDESCryptoServiceProvider cryptoProvider = new TripleDESCryptoServiceProvider();
    MemoryStream ms = new MemoryStream();
    CryptoStream cs = new CryptoStream(ms, cryptoProvider.CreateEncryptor(encryptionKey, initializationVector), CryptoStreamMode.Write);
    StreamWriter sw = new StreamWriter(cs);
    sw.Write(value);
    sw.Flush();
    cs.FlushFinalBlock();
    ms.Flush();
    //convert back to a string
    return Convert.ToBase64String(ms.GetBuffer(), 0, (int)ms.Length);
  } else {
    return "";
  }
}

如您所见,该算法采用 2 个参数 - 一个“加密密钥”和一个“初始化向量”。

现在我需要用 Java 编写一个 DES 加密/解密函数,与这个函数并行,这样,如果您提供相同的加密密钥和初始化向量,您将能够在 Java 中解密用 C# 加密的东西。 (穿上 Java 工作服,自上次使用 Java 以来大约 10 年的灰尘,谷歌在 Java 中进行 DES 加密......)

找到了一个不错的 Java DES 加密方法here。但是 - 哦,天哪,事实证明这个算法坚持使用正好 8 个字节的初始化向量; .NET 代码使用 24 字节的初始化向量!

现在呢?为什么 Java 坚持使用 8 字节的初始化向量?以及如何解密使用 24 字节初始化向量加密的内容?

【问题讨论】:

  • 如果您因为需要安全性而加密此数据并且需要使用 DES 版本,我会选择 168 位的 TripleDES,而不是 56 位的标准 DES。如果您有出于任何原因需要保护的数据,标准 DES 太容易被破解。

标签: c# java encryption cryptography


【解决方案1】:

您是否尝试过在 Java 代码中使用 24 字节初始化向量的前 8 个字节?我通过搜索和查看源代码看到的所有内容都表明,由于 Triple DES 的块大小为 8 字节,因此只会使用前 8 个字节。我真的很惊讶 .NET 代码没有引发像 this question 中提到的异常,因为 IV 与算法的块大小不匹配。另请参阅this question 以了解成功使用 8 字节 IV 的示例。

.NET 代码中的另一个挑战是填充和密码模式使用默认值。尽管here 的注释表明默认密码模式是CBC,但我不知道.NET 将用于这些。我没有看到任何关于填充的内容,但从互操作性示例here 看来,CBC 和 PKCS5Padding 似乎可以工作。不过,我会犹豫是否要依赖默认值来实现这样的互操作性,因为它们可能会出现问题。

来自 Java 背景,我不太确定使用 24 字节 IV 的 C# 代码中发生了什么,但 Java 强制执行的 8 字节 IV 对我来说似乎是正确的。不过,我总是对被证明是错误的并学习新东西感兴趣。 @Tim 提到的 Bouncycastle 也强制执行相同的约束,而且似乎 .NET 通常也会这样做。

【讨论】:

  • 你这个天才,你!我将字节数组截断为 8 个字节,效果很好!谢谢!
【解决方案2】:

From MSDN:

IV 属性自动设置 到一个新的随机值,每当你 创建其中一个的新实例 SymmetricAlgorithm 类或当你 手动调用 GenerateIV 方法。 IV 属性的大小必须是 与 BlockSize 属性相同。

所以在我看来,您可以简单地更改 BlockSize 属性,然后您可以将 IV 设置为您需要的任何大小。

编辑

根据我在研究中收集到的信息,似乎 DES 加密算法的所有实现都使用 8 个字节(64 位,其中 8 个被丢弃,剩下 56 个字节)。 TripleDES (3DES) 允许使用 24 字节(或 192 位,其中 24 个被丢弃,剩下 168 位)的密钥。

您似乎需要在 Java 中使用 TripleDES 算法(有几个库可用,example、SO Question),或者您需要使用 .网。

【讨论】:

  • @Shaul - 我认为他的观点是您可以更改 .NET 实现以使用 8 字节 IV,然后 Java 方法将拥有它想要的东西。
  • @Tim - .NET 就是这样;我无法改变这一点,此外,我们已经有了加密数据,我们现在需要能够在 Java 中解密。
  • 好的,那行不通,但是从您的原始帖子中不清楚您无法更改 .NET 实现和/或数据已经加密。跨度>
  • @Tim - 引用:“我怎样才能解密使用 24 字节初始化向量加密的东西?”
  • @Shaul,不值得争论语义。显然,有人可能会以不同的方式阅读您的问题,因为 FreeAsInBeer 和我都这样做了。我会看看我能挖掘出什么来真正回答你的问题。
【解决方案3】:

您是否查看过用于 Java 的 Bouncy Castle 库?我无法从他们的(非常稀疏的)文档和示例中看出,但它似乎是一个广泛使用的库,所以我希望它会那么灵活。如果您还没有,至少值得一看。

【讨论】:

    猜你喜欢
    • 2016-12-10
    • 1970-01-01
    • 2017-08-25
    • 2019-06-02
    • 1970-01-01
    • 1970-01-01
    • 2012-02-06
    • 2019-11-10
    • 2021-12-30
    相关资源
    最近更新 更多