androidcryptographyaes

How to initialize cipher.init(Cipher.DECRYPT_MODE, masterKey) - IV required when decrypting. Use IvParameterSpec or AlgorithmParameters to provide it


I can not understand what wrong in this code, this is standard Android key-value service without any fantasy

 private SecretKey decryptDataKey(String encryptedDataKeyString) throws NoSuchAlgorithmException, InvalidKeyException,
        NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, UnrecoverableKeyException, java.security.KeyStoreException, InvalidAlgorithmParameterException, NoSuchProviderException {
         java.security.Key masterKey = getOrCreateKey(); 
         Cipher cipher = Cipher.getInstance(transformation);
         cipher.init(Cipher.DECRYPT_MODE, masterKey); // No GCMParameterSpec
         byte[] encryptedDataKey = android.util.Base64.decode(encryptedDataKeyString, android.util.Base64.DEFAULT); // Correct Base64 class
         byte[] decryptedDataKey = cipher.doFinal(encryptedDataKey);
         return new SecretKeySpec(decryptedDataKey, KeyProperties.KEY_ALGORITHM_AES);
     } 

master key is present, transformation = "AES/GCM/NoPadding"

masterkey present

but code produced error "java.security.InvalidKeyException: IV required when decrypting. Use IvParameterSpec or AlgorithmParameters to provide it."

follow documentation all looking good https://developer.android.com/reference/javax/crypto/Cipher#init(int,%20java.security.Key)

I ask Gemini and other Ai, and even ask specially implement this recipe Issue while using Android fingerprint: IV required when decrypting. Use IvParameterSpec or AlgorithmParameters to provide it , but failed. AI also understand what going wrong in line cipher.init(Cipher.DECRYPT_MODE, masterKey)


Solution

  • follow @Topaco advice "All modes (with the exception of the insecure ECB mode) require an IV for decryption. For GCM, the recommended IV length is 12 bytes (although other IV lengths are technically possible). It is common to concatenate IV (because it is not secret) and ciphertext during encryption" my current workable code is:

    private SecretKey decryptDataKey(byte[] encryptedDataKey, byte[] iv) throws NoSuchAlgorithmException, InvalidKeyException,
            NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, UnrecoverableKeyException, java.security.KeyStoreException, InvalidAlgorithmParameterException, NoSuchProviderException {
        Key masterKey = getOrCreateKey();
        Cipher cipher = Cipher.getInstance(transformation);
        GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(gcmTagLength, iv);
        cipher.init(Cipher.DECRYPT_MODE, masterKey, gcmParameterSpec);
        byte[] decryptedDataKey = cipher.doFinal(encryptedDataKey);
        return new SecretKeySpec(decryptedDataKey, KeyProperties.KEY_ALGORITHM_AES);
    }