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

  1. Verify the ciphertext was produced by encryptData with the same IV-prefix format and app version
  2. Re-encrypt the data with the current library format
  3. 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

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


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)