首页 > 解决方案 > Android解密抛出java.security.InvalidAlgorithmParameterException:IV必须在CBC模式下指定

问题描述

尽管检查了我的 IV 和派生密钥对于加密和解密都是相等的,但它仍然会引发相同的错误。字节数组将加密没有问题,但解密总是失败。我的解密和加密代码如下:

private final static int BLOCK_SIZE = 256;
private final static int IV_SIZE = 16;
private final static int ITERATION_COUNT = 10;
private final static String ENCRYPTION_ALGORITHM = "PBKDF2WithHmacSHA256";
private final static String ALGORITHM = "AES/CBC/PKCS5Padding";

public byte[] encryptByteArray(byte[] plaintext, String fileName) throws InvalidKeyException
{
    extractIVfromName(fileName);
    genKey();
    
    try {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        GCMParameterSpec parameterSpec = new GCMParameterSpec(BLOCK_SIZE, iv);

        Log.d("encryptByteArray", "Size: " + plaintext.length + " IV SPEC: " +
                Base64.encodeToString(parameterSpec.getIV(), Base64.DEFAULT) + "DerivedKey: " +
                Base64.encodeToString(derivedKey.getEncoded(), Base64.DEFAULT));

        cipher.init(Cipher.ENCRYPT_MODE, derivedKey, parameterSpec);
        return cipher.doFinal(plaintext);
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (NoSuchPaddingException e) {
        e.printStackTrace();
    } catch (BadPaddingException e) {
        e.printStackTrace();
    } catch (IllegalBlockSizeException e) {
        e.printStackTrace();
    } catch (InvalidAlgorithmParameterException e) {
        e.printStackTrace();
    }
    return null;
}

在这里我们进行了解密,发生错误的地方:

public byte[] decryptByteArray(byte[] ciphertext, String fileName) throws InvalidKeyException
{
    extractIVfromName(fileName);
    genKey();
    try {
        //IV fails for some reason
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        GCMParameterSpec parameterSpec = new GCMParameterSpec(BLOCK_SIZE, iv);
        Log.d("decryptByteArray", "Size: " + ciphertext.length + " IV SPEC: " +
                Base64.encodeToString(parameterSpec.getIV(), Base64.DEFAULT) + "DerivedKey: " +
                Base64.encodeToString(derivedKey.getEncoded(), Base64.DEFAULT));
        cipher.init(Cipher.DECRYPT_MODE, derivedKey, parameterSpec);
        return cipher.doFinal(ciphertext);

    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (InvalidAlgorithmParameterException e) {
        e.printStackTrace();
    } catch (NoSuchPaddingException e) {
        e.printStackTrace();
    } catch (BadPaddingException e) {
        e.printStackTrace();
    } catch (IllegalBlockSizeException e) {
        e.printStackTrace();
    }
    return null;
}

调试日志的一个例子给出了这个:

2020-07-26 22:40:03.667 9089-9089/com.iso.gallery256 D/decryptByteArray: Size: 45312 IV SPEC: NWZmYmUzZGItZGE4MS00Yw==
    DerivedKey: pa2OYoRLjTphldeSi1L6EQCmlXTzQJLeXgPIuu6kRus=

2020-07-26 22:40:00.184 9089-9089/com.iso.gallery256 D/encryptByteArray: Size: 45307 IV SPEC: NWZmYmUzZGItZGE4MS00Yw==
    DerivedKey: pa2OYoRLjTphldeSi1L6EQCmlXTzQJLeXgPIuu6kRus=

我认为问题不在于 IV 或密钥的生成方式,因为它们在解密和加密方面完全相同,而是与我的密码选项有关。

标签: javaandroidencryption

解决方案


推荐阅读