我有一个.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 "";
}
}
如您所见,该算法采用2个参数-“加密密钥”和“初始化向量”。
现在,我需要用Java编写DES加密/解密函数,并与该函数并行进行,这样,如果您提供相同的加密密钥和初始化向量,就可以在Java中解密使用C#加密的内容。(从Java总体来看,自从上次使用Java以来已有十多年的历史了,谷歌使用Java进行DES加密...)
在这里找到了不错的Java DES加密方法。但是-亲爱的,事实证明,该算法坚持使用恰好8个字节的初始化矢量;.NET代码使用24字节的初始化向量!
怎么办?Java为什么要坚持使用8字节的初始化向量?以及如何解密使用24字节初始化向量加密的内容?
您是否尝试过在Java代码中使用24字节初始化向量的前8个字节?我通过搜索和查看源代码看到的所有内容都表明,由于Triple DES的块大小为8字节,因此仅会使用前8个字节。我真的很惊讶,.NET代码没有引发像本问题中提到的那样的异常,因为IV与算法的块大小不匹配。另外,有关成功使用8字节IV的示例,请参见此问题。
.NET代码中的另一个挑战是,将默认值用于填充和密码模式。我不知道这些将使用什么.NET,尽管这里的说明表明默认的密码模式是CBC。我没有提到填充,但是从这里的互操作性示例来看,CBC和PKCS5Padding似乎可以工作。我会犹豫是否使用默认值来实现这种互操作性,因为它们可能会出现问题。
来自Java背景,我不太确定使用24字节IV的C#代码中发生了什么,但是Java强制执行的8字节IV对我来说是正确的。我一直对被证明是错误的和学习新东西很感兴趣。@Tim提到的Bouncycastle也强制执行相同的约束,并且.NET似乎也这样做。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句