MuntashirAkon/AppManager · error · InvalidAlgorithmParameterException
Invalid IV length
Error message
Invalid IV length ${iv_len} What it means
decryptData reads a one-byte IV length prefix from the encrypted blob and validates it against AES_GCM_IV_LENGTH before reading the IV and decrypting. A mismatched prefix means the blob was not produced by this format (or is corrupted), so it throws InvalidAlgorithmParameterException rather than producing garbage plaintext.
Solutions
- Verify the ciphertext was produced by encryptData with the same IV-prefix format and app version
- Re-encrypt the data with the current library format
- Add format/version detection before calling decryptData
Example fix
// before
int iv_len = encryptedBuffer.get();
if (iv_len != AES_GCM_IV_LENGTH) {
throw new InvalidAlgorithmParameterException("Invalid IV length " + iv_len);
}
// after
if (encryptedBuffer.remaining() < 1) {
throw new InvalidAlgorithmParameterException("Encrypted data too short");
}
int iv_len = encryptedBuffer.get();
if (iv_len != AES_GCM_IV_LENGTH) {
throw new InvalidAlgorithmParameterException("Invalid IV length " + iv_len + "; not in expected format");
} Defensive patterns
Strategy: validation
Validate before calling
if (encryptedData == null || encryptedData.length < 1 + AES_GCM_IV_LENGTH) {
throw new IllegalArgumentException("Blob too short to contain IV prefix");
}
if (encryptedData[0] != AES_GCM_IV_LENGTH) {
throw new IllegalArgumentException("Unrecognized ciphertext format");
} Try / catch
try {
return CompatUtil.decryptData(encryptedData, key);
} catch (InvalidAlgorithmParameterException | BadPaddingException e) {
// not in expected format or wrong key; surface as data-format error
throw new DataFormatException("Ciphertext not produced by this app", e);
} Prevention
- Always round-trip data through the same encrypt/decrypt pair
- Version-tag or magic-prefix encrypted blobs
- Guard against truncated files before decrypting
When it happens
Trigger: Decrypting a byte array whose first byte is not AES_GCM_IV_LENGTH — data written by a different crypto format/version, truncated files, or blobs missing the length-prefix header.
Common situations: Reading files encrypted by older app versions or other tools; truncated/corrupted storage; passing ciphertext that lacks the IV-prefix framing.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Invalid IV length
- Could not decrypt encrypted password.
- Could not get crypto
- Could not get crypto " + mBackupInfo.crypto
- Could not load AES local protection key from keystore
AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12).
Data as JSON: /api/errors/c8da7cd93f1596e4.
Report an issue: GitHub.
Appendix: source
Thrown at app/src/main/java/io/github/muntashirakon/AppManager/crypto/ks/CompatUtil.java:248
return new AesEncryptedData(iv, encryptedData);
}
/**
* Decrypt given data.
*
* @param context The context holding the application shared preferences
* @param encryptedData Data to be decrypted
* @return Decrypted data.
*/
@NonNull
public static byte[] decryptData(@NonNull Context context, @NonNull byte[] encryptedData)
throws NoSuchPaddingException, NoSuchAlgorithmException, CertificateException,
InvalidKeyException, KeyStoreException, UnrecoverableKeyException, IllegalBlockSizeException,
NoSuchProviderException, InvalidAlgorithmParameterException, IOException, ShortBufferException, BadPaddingException {
ByteBuffer encryptedBuffer = ByteBuffer.wrap(encryptedData);
int iv_len = encryptedBuffer.get();
if (iv_len != AES_GCM_IV_LENGTH) {
throw new InvalidAlgorithmParameterException("Invalid IV length " + iv_len);
}
byte[] iv = new byte[AES_GCM_IV_LENGTH];
encryptedBuffer.get(iv);
Cipher cipher = Cipher.getInstance(AES_GCM_CIPHER_TYPE);
SecretKeyAndVersion keyAndVersion = getAesGcmLocalProtectionKey(context);
AlgorithmParameterSpec spec;
if (keyAndVersion.getAndroidVersionWhenTheKeyHasBeenGenerated() >= Build.VERSION_CODES.M) {
spec = new GCMParameterSpec(AES_GCM_KEY_SIZE_IN_BITS, iv);
} else {
spec = new IvParameterSpec(iv);
}
cipher.init(Cipher.DECRYPT_MODE, keyAndVersion.getSecretKey(), spec);View on GitHub (pinned to 0152f468fc)