首页 > 解决方案 > 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)

我不明白为什么密钥长度无效

标签: javajavax.crypto

解决方案


推荐阅读