我有一个.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(),(int)ms.Length);
} else {
return "";
}
}
如您所见,该算法采用2个参数 – “加密密钥”和“初始化向量”.
现在我需要用Java编写DES加密/解密函数,与此函数并行,这样如果你提供相同的加密密钥和初始化向量,你将能够用Java解密用C#加密的东西. (关于Java工作服,自上次使用Java以来大约10年的时间,以及Java中用于DES加密的Googles ……)
找到了一个不错的Java DES加密方法here.但是 – 哦亲爱的,事实证明这个算法坚持一个正好8个字节的初始化向量; .NET代码使用24字节的init向量!
怎么办?为什么Java坚持使用8字节的init向量?我如何解密使用24字节初始向量加密的内容?
最佳答案
您是否尝试过在Java代码中使用24字节初始化向量的前8个字节?我通过搜索和查看源代码看到的所有内容都表明只使用前8个字节,因为Triple DES具有8字节的块大小.我很惊讶.NET代码没有像this question中提到的那样引发异常,因为IV与算法的块大小不匹配.另请参见this question,以获取成功使用8字节IV的示例.
.NET代码中的另一个挑战是默认值用于填充和密码模式.我不知道.NET将用于那些,虽然备注here表明默认密码模式是CBC.我没有提到填充,但是从互操作性示例here来看,似乎CBC和PKCS5Padding都能正常工作.我会毫不犹豫地依赖默认设置这样的互操作性,因为它们可能会有问题.
来自Java背景我不太确定使用24字节IV的C#代码中发生了什么,但Java强制执行的8字节IV似乎对我来说是正确的.我总是对被证明是错误的并且学习新东西感兴趣. @Tim提到的Bouncycastle也强制实施同样的约束,看起来.NET通常也会这样做.