2011-05-19 40 views
5

我有一个字符串做DES加密的.NET方法:Java与.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加密的Googles ...)

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

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

+0

如果你正在加密这个数据,因为你需要安全性,并且你需要使用DES的一个版本,我会使用168位的TripleDES,而不是56位的标准DES。如果您的数据因任何原因需要安全,标准DES很容易被破解。 – FreeAsInBeer 2011-05-19 15:46:54

回答

2

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

.NET代码中的另一个挑战是默认值用于填充和密码模式。我不知道是什么。NET将用于那些,虽然备注here表明默认密码模式是CBC。我看不到填充,但从互操作性示例here看来,CBC和PKCS5Padding似乎可以工作。尽管如此,我仍然犹豫依靠默认设置来实现互操作性,因为它们可能存在问题。

来自Java背景我不太确定使用24字节IV的C#代码是怎么回事,但是由Java执行的8字节IV似乎对我来说是正确的。我总是有兴趣证明自己错了,并且学习新东西。 @Tim提到的Bouncycastle也强制执行这个相同的约束,看起来像.NET通常也是这样。

+0

你是天才,你!我将字节数组截断为8个字节,并且它完美地工作!谢谢! – 2011-05-19 15:05:18

2

From MSDN

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

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

编辑

从我所聚集在我的研究,似乎是(让你有56个字节64位,其中8项获得扔掉,)DES加密算法使用8个字节的所有实现。 TripleDES(3DES)允许24个字节的密钥(或192位,其中24位被丢弃,留下168位)。

看来,你要么需要在Java中使用的TripleDES算法(几个库可用,exampleSO Question),或者你需要使用.NET中的常规DES加密算法重新加密数据。

+0

嗯...这对.NET很好...我正在寻找Java解决方案... – 2011-05-19 11:59:57

+0

@Shaul - 我认为他的观点是,您可以将.NET实现更改为使用8字节的IV,然后Java方法将会有它想要的。 – Tim 2011-05-19 12:02:51

+0

@Tim - .NET就是它;我无法改变这一点,此外,我们已经拥有了我们现在需要能够用Java解密的加密数据。 – 2011-05-19 12:03:59

0

你看了一下用于Java的Bouncy Castle库吗?我无法从他们的(非常稀少的)文档和样本中看出来,但它似乎是一个广泛使用的库,所以我希望它能够灵活。值得一看,至少如果你还没有。