Java 与 .NET 中的 DES 加密 - 为什么不同
本文关键字:为什么不 加密 DES NET 中的 Java | 更新日期: 2023-09-27 17:56:50
我有一个.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以来大约10年了,Googles在Java中进行DES加密......
在这里找到了一个不错的Java DES加密方法。 但是 - 哦,亲爱的,事实证明该算法坚持使用正好 8 个字节的初始化向量;.NET 代码使用 24 字节的初始化向量!
现在怎么办? 为什么Java坚持使用8字节的初始化向量? 如何解密使用 24 字节 init 向量加密的内容?
您是否尝试过在 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通常也会这样做。
来自 MSDN:
自动设置 IV 属性 到新的随机值,只要你 创建其中一个 对称算法类或当您 手动调用生成 IV 方法。 IV 属性的大小必须为 与 BlockSize 属性相同。
所以在我看来,您可以简单地更改 BlockSize 属性,然后将 IV 设置为您需要的任何大小。
编辑
从我在研究中收集到的信息来看,似乎 DES 加密算法的所有实现都使用 8 个字节(64 位,其中 8 位被丢弃,留下 56 个字节)。TripleDES (3DES) 允许 24 个字节的密钥(或 192 位,其中 24 位被丢弃,留下 168 位)。
似乎您要么需要在 Java 中使用 TripleDES 算法(有几个库可用,例如 SO Question),要么需要使用 .NET 中的常规 DES 加密算法重新加密数据。
你看过 Java 的 Bouncy Castle 库吗?我无法从他们的(非常稀疏的)文档和示例中分辨出来,但它似乎是一个广泛使用的库,所以我希望它会那么灵活。至少值得一看,如果你还没有的话。