我正在开发一个需要在 Java 中进行 3DES 加密的项目。问题是我已经(并将继续)提供了一个 128 位十六进制密钥,例如“0123456789ABCDEF0123456789ABCDEF”。转换为字节没有问题。然而,问题是Java Cryptographic Extensions API 会卡在这个密钥上,说它是无效的。我收集到每个字节的 MSB 只是一个奇偶校验位,所以 JCE 希望我删除那些(或者我认为)。然而,在 .NET 中,我可以指定提供的密钥,它会安静地处理加密/解密,没有任何抱怨。
有什么方法可以从我提供的密钥类型中生成 JCE 期望的密钥类型?
我发现 JCE 允许您为 DES 加密指定一个 8 字节的密钥,因此我尝试使用提供的一半密钥将 3DES 实现为 DES EDE。但是,我仍然得到与 .NET 不一致的结果。
这是Java代码:
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.spec.IvParameterSpec;
public class Main{
public static void main(String[] args) throws Exception {
byte [] plain = "I eat fish every day".getBytes("utf-8");
byte [] keyBytes = new byte [] { (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00
};
byte [] key2Bytes = new byte [] { (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0 }; // actual keys replaced with dummies.
SecretKey keySpec = new SecretKeySpec(keyBytes, "DES");
SecretKey keySpec2 = new SecretKeySpec(key2Bytes, "DES");
IvParameterSpec iv = new IvParameterSpec(new byte[8]);
Cipher e_cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
Cipher cipher = Cipher.getInstance("DES/CBC/NoPadding");
e_cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
cipher.init(Cipher.DECRYPT_MODE, keySpec2, iv);
byte [] cipherText = e_cipher.doFinal(plain);
cipherText = cipher.doFinal(cipherText);
cipherText = e_cipher.doFinal(cipherText);
System.out.println("Ciphertext: " + new sun.misc.BASE64Encoder().encode(cipherText));
}
}
这是.NET代码:
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace EncryptionDemo
{
class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Hello World!");
// TODO: Implement Functionality Here
var plainBytes = Encoding.UTF8.GetBytes("I eat fish every day");
var keyBytes = new byte [] { 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00 };
var tripleDES = TripleDESCryptoServiceProvider.Create();
var transform = tripleDES.CreateEncryptor(keyBytes, new byte [8]);
var memStream = new MemoryStream();
var cStream = new CryptoStream(memStream, transform, CryptoStreamMode.Write);
cStream.Write(plainBytes, 0, plainBytes.Length);
cStream.FlushFinalBlock();
//memStream.Position = 0;
var cipherBytes = memStream.ToArray();
Console.WriteLine("Ciphertext: " + Convert.ToBase64String(cipherBytes));
Console.Write("Press any key to continue . . . ");
Console.ReadKey(true);
}
}
两者都产生不同的输出(Base64 字符串中的某些字符是相同的)