Android解密抛出java.security.InvalidAlgorithmParameterException:在CBC模式下必须指定IV

huangapple 未分类评论48阅读模式
英文:

Android Decryption Throwing java.security.InvalidAlgorithmParameterException: IV must be specified in CBC mode

问题

尽管我已经检查了加密和解密的初始向量(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或密钥的生成方式,因为它们在解密和加密时都完全相同,而是在于我的密码选项。

英文:

Despite checking that both my IV and derived keys are equal for encryption and decryption, it still throws the same error. The byte array will encrypt no problem, but decryption always fails. My decryption and encryption code looks like:

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

And here we have decryption, where the error is occuring:

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

An example of the debug log gives this:

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=

I don't think the problem is with how the IV or key are generated, since they come out exactly the same for decryption and encryption, but rather with my cipher options.

huangapple
  • 本文由 发表于 2020年7月27日 10:45:41
  • 转载请务必保留本文链接:https://java.coder-hub.com/63107993.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定