1

I have the following Decryption code from a C# App written by a colleague:

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;
}

Piecing together the equivalent cryptography, I currently have the Java equivalent as:

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;
}

But it's throwing an exception:

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)

I don't understand why the key length is invalid

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Black
  • 5,023
  • 6
  • 63
  • 92
  • 1
    Does this answer your question? ["Wrong algorithm" Error when trying to Decrypt in Java](https://stackoverflow.com/questions/9670602/wrong-algorithm-error-when-trying-to-decrypt-in-java) – Phu Ngo May 12 '21 at 14:34
  • 2
    Change the line " SecretKey secretKeyAES = new SecretKeySpec(secretKey.getEncoded(), "AES");" to " SecretKey secretKeyAES = new SecretKeySpec(key, "AES");". Your issue is that you derive the key and iv via PBKDF2, split the result in key and iv BUT you use the complete PBKDF2 output (48 bytes long) as key. – Michael Fehr May 12 '21 at 14:54

0 Answers0