java - Rfc2898DeriveBytes 的 Java 等效解密抛出 Invalid AES Key Length
问题描述
我有以下来自同事编写的 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)
我不明白为什么密钥长度无效
解决方案
推荐阅读
- c# - 将用户控件动态添加到页面会使 UC 内部的控件为空
- c++ - 我可以从它的 cmake 文件中恢复丢失的源代码吗?
- python - 当互联网被另一个应用程序使用时,Python Selenium 网络爬虫会变慢
- python - 将数据插入 ttk.treeview 小部件到特定列
- autohotkey - 从 ClassNN 复制文本
- view - 如何从 PIVOT SQL 创建视图
- ruby-on-rails - 用文本和 url 替换 markdown 链接
- python - 保存带有外键引用的序列化程序时 Django 失败
- r - 如何获取具有变量最大值的所有行
- mongodb - 如何配置 mongodb 以删除旧的日志文件?