C# Java与.NET中的DES加密-为什么不同?

C# Java与.NET中的DES加密-为什么不同?,c#,java,encryption,cryptography,C#,Java,Encryption,Cryptography,我有一个.NET方法对字符串进行DES加密: public static string EncryptTripleDES(string value, byte[] encryptionKey, byte[] initializationVector) { if (!value.IsNullOrEmpty()) { TripleDESCryptoServiceProvider cryptoProvider = new TripleDESCryptoServiceProvider();

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

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 "";
  }
}
如您所见,该算法采用两个参数—一个“加密密钥”和一个“初始化向量”

现在,我需要用Java编写一个DES加密/解密函数,与此函数并行,这样,如果您提供相同的加密密钥和初始化向量,您就能够用Java解密在C#中加密的内容。(穿上Java工作服,掸掉上次使用Java大约10年后的灰尘,谷歌在Java中使用DES加密…)

找到了一种不错的JavaDES加密方法。但是-哦,天哪,结果证明这个算法坚持一个8字节的初始化向量;NET代码使用24字节的初始向量

现在怎么办?为什么Java坚持使用8字节的init向量?如何解密使用24字节初始向量加密的内容?

IV属性是自动设置的 当您 创建其中一个的新实例 对称算法类或 手动调用GenerateIV方法。 IV属性的大小必须为 与BlockSize属性相同

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

编辑

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


您可能需要在Java中使用TripleDES算法(有几个库可用),或者需要在.NET中使用常规DES加密算法重新加密数据。

您看过Java库了吗?我无法从他们(非常稀少的)文档和示例中分辨出来,但它似乎是一个广泛使用的库,所以我希望它能如此灵活。至少如果您还没有这样做,那么值得一看。

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

NET代码中的另一个挑战是填充和密码使用默认值。我不知道.NET将使用什么来实现这些功能,尽管备注表明默认的密码模式是CBC。我没有提到填充,但从互操作性示例来看,CBC和PKCS5P添加似乎可以工作。不过,我不太愿意依赖默认值来实现这样的互操作性,因为它们可能会有问题


来自Java的背景,我不太确定使用24字节IV的C#代码中发生了什么,但是Java强制使用的8字节IV对我来说似乎是正确的。我总是对被证明是错误的和学习一些新的东西感兴趣。@Tim提到的Bouncycastle也实施了同样的约束,就像.NET通常也一样。

@Shaul-我认为他的观点是,您可以将.NET实现更改为使用8字节IV,然后Java方法将得到它想要的。@Tim-.NET就是它的样子;我不能改变这一点,而且,我们已经有了加密数据,我们现在需要能够用Java解密。好的,那么这将不起作用,但从您最初的帖子中不清楚您不能更改.NET实现和/或数据已经加密。@Tim-quote:“如何解密使用24字节初始向量加密的内容?“@Shaul,这不值得争论。很明显,有人可能会以不同的方式解读你的问题,因为弗里亚辛贝尔和我都这么做了。我看看我能找出什么来真正回答你的问题。你这个天才,你!我将字节数组截断为8个字节,它工作得非常好!非常感谢。如果您加密这些数据是因为您需要安全性,并且您需要使用DES版本,那么我将使用TripleDES(168位),而不是标准DES(56位)。如果您有出于任何原因需要安全的数据,那么标准DES很容易被破解。