Android Security: Beware of the default IV!
A quick one today.
A couple of people I have spoken to recently have been unaware of the need to ensure a random IV is being used when performing AES encryption on Android.
What is an IV?
In cryptography, an initialization vector (IV) or starting variable (SV) is a fixed-size input to a cryptographic primitive that is typically required to be random or pseudorandom. Randomization is crucial for encryption schemes to achieve semantic security, a property whereby repeated usage of the scheme under the same key does not allow an attacker to infer relationships between segments of the encrypted message. For block ciphers, the use of an IV is described by the modes of operation. Wikipedia
The unawareness seems to fall into two camps:
- I didn’t know I needed to use an IV
- I am using the IV that is generated by the Cipher
I didn’t know I needed to use an IV
I am using the IV that is generated by the Cipher
Potentially an Uh oh!
Poking around a little, I can see that on old versions of Android (tested 4.3) the
AndroidOpenSSL provider can return an all
0 IV with the below, whereas the same code on 7 will spit out seemingly-random IVs.
Using the newer
KeyGenParameterSpec APIs and the
AndroidKeyStore Provider seems to be fine regarding this issue from the small amount of testing I have done. The IV is prepended to the ciphered output
bytes by default.
Enforcing a random IV
It may be worth explicitly declaring an IV to avoid the potential of the default one zero-ing out, which from the above depends on the providers implementation in use. This can be as simple as:
Worth being aware of
isRandomizedEncryptionRequired() exists if you want to manually ensure the IV is randomised, otherwise
cipher.init will throw if an IV is supplied.
If interested in Android security take a look at doridori/Android-Security-Reference