我有以下来自同事编写的 C# 应用程序的解密代码:
private static string UrlEncryptionKey = "x0iiR!RG@753!"; // not real values here
private static byte[] salt = new byte[] { 0x41, 0x71, 0x61, 0x6e, 0x21, 0x4d, 0x65, 0x64, 0x76, 0x64, 0x63, 0x62, 0x72 }
public static string Decrypt(String cipherText)
{
byte[] cipherBytes = Convert.FromBase64String(cipherText);
using (Aes encryptor = Aes.Create())
{
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(UrlEncryptionKey, salt);
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(cipherBytes, 0, cipherBytes.Length);
cs.Close();
}
cipherText = Encoding.Unicode.GetString(ms.ToArray());
}
}
return cipherText;
}
将等效的密码学拼凑在一起,我目前将 Java 等效为:
public static String Decrypt(String cipherText) throws Exception {
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
PBEKeySpec pbeKeySpec = new PBEKeySpec(UrlEncryptionKey.toCharArray(), salt, 1000, 384);
Key secretKey = factory.generateSecret(pbeKeySpec);
byte[] key = new byte[32];
byte[] iv = new byte[16];
System.arraycopy(secretKey.getEncoded(), 0, key, 0, 32);
System.arraycopy(secretKey.getEncoded(), 32, iv, 0, 16);
AlgorithmParameterSpec ivSpec = new IvParameterSpec(iv);
SecretKey secretKeyAES = new SecretKeySpec(secretKey.getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secretKeyAES, ivSpec);
byte[] decoded = Base64.getDecoder().decode(cipherText.getBytes("UTF-8"));
byte[] original = cipher.doFinal(decoded);
String originalString = new String(original, "UTF-8");
return originalString;
}
但它抛出了一个异常:
Exception in thread "main" java.security.InvalidKeyException: Invalid AES key length: 48 bytes
at com.sun.crypto.provider.AESCrypt.init(AESCrypt.java:87)
at com.sun.crypto.provider.CipherBlockChaining.init(CipherBlockChaining.java:93)
at com.sun.crypto.provider.CipherCore.init(CipherCore.java:591)
at com.sun.crypto.provider.AESCipher.engineInit(AESCipher.java:346)
at javax.crypto.Cipher.implInit(Cipher.java:809)
at javax.crypto.Cipher.chooseProvider(Cipher.java:867)
at javax.crypto.Cipher.init(Cipher.java:1399)
at javax.crypto.Cipher.init(Cipher.java:1330)
at scratch.AESUtil.Decrypt(AESUtil.java:55)
at scratch.AESUtil.main(AESUtil.java:93)
我不明白为什么密钥长度无效