Cipher.getInstance("AES")
Android Studio's Lint complains about the above code as follows:
cipher.getinstance should not be called without setting the encryption mode and padding
The above code works perfectly as explained by an SO answer.
Could anyone shed some light on how to use cipher.getinstance() correctly?
When instantiating a Cipher
instance, algorithm, mode, and padding should always be explicitly specified, e.g.:
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
If only the algorithm is specified, provider-specific values for mode and padding are applied, see Cipher
in the Android or Java documentation. This has a number of error-prone disadvantages and should therefore strictly be avoided:
The Lint tool points out these problems with its warning Cipher.getInstance should not be called without setting the encryption mode and padding. By the way, the Lint report also warns about the insecurity of ECB when it is specified with AES/ECB/PKCS5Padding
: ECB encryption mode should not be used.
In contrast, CBC, when specified with AES/CBC/PKCS5Padding
, does not trigger a warning in Lint.
Although CBC is more secure than ECB, CBC only supports confidentiality. Therefore, authenticated encryption, which provides authenticity and integrity in addition to confidentiality, should be preferred, e.g. GCM. Since GCM is based on CTR, i.e. a stream cipher mode, no padding is required, unlike block cipher modes such as ECB or CBC (see Block cipher mode of operation). Thus, GCM is specified with AES/GCM/NoPadding
.
Here you can find a post regarding the difference between CBC and ECB: Should I use ECB or CBC encryption mode for my block cipher? and here regarding the difference between CBC and GCM: What is the difference between CBC and GCM mode?.
Finally, a little note about PKCS#5 padding: what is called PKCS#5 padding in the Java/Android world for historical reasons is actually PKCS#7 padding. Here you can find more details about this topic: What is the difference between PKCS#5 padding and PKCS#7 padding?.