1
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?

Hong
  • 17,643
  • 21
  • 81
  • 142
  • 3
    You should specify algorithm, mode and padding, e.g. `AES/CBC/PKCS5Padding`. If you don't specify the mode and padding when instantiating the cipher instance, provider-dependent default values are used, which are often ECB mode and PKCS#5 padding. However, ECB is an insecure mode that definitely should be avoided, which can only be ensured by explicitly specifying the mode. Another reason is that cross-platform problems can occur if different providers with different default values are involved. – Topaco Apr 03 '22 at 18:37
  • 2
    You should explicitly specify to mode and padding, for example: `AES/CBC/NoPadding`. See https://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html for the possible values. – Richard Heap Apr 03 '22 at 18:41
  • 1
    @RichardHeap CBC should not be used without padding, and we prefer authenticated (AEAD) ciphers such as GCM for general purpose use. – Maarten Bodewes Apr 03 '22 at 19:22
  • 1
    Besides the points that @Topaco makes, you should also note that not specifying the cipher or padding mode doesn't really help readability. I'd even argue that it violates the principle of least surprise. – Maarten Bodewes Apr 03 '22 at 19:23
  • 2
    Finally, a remark for Hong: the goal of cryptography is **not** to make anything **work**. It is to **secure something**, which would probably "work" just fine without cryptography in the first place. So remarks like "the code works perfectly" doesn't really say anything. – Maarten Bodewes Apr 03 '22 at 19:25
  • Thank you all. @Topaco could you turn your comment into an answer for me to accept? Using "AES/CBC/PKCS5Padding" makes the warning go away. This encryption is optional for the situation. In other words, it is nice to have some encryption. It is not a big deal if some spends to effort to crack it. – Hong Apr 04 '22 at 14:45
  • You' re welcome. I've turned my comments and those of others into an answer. – Topaco Apr 04 '22 at 17:47

1 Answers1

2

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:

  • Many providers use ECB mode and PKCS#5 padding as default values, e.g. the BouncyCastle provider on Android (tested for API level 28 und 29). However, ECB mode is insecure and should therefore not be applied, see Why shouldn't I use ECB encryption?. To prevent the use of ECB mode, the mode needs to be explicitly specified.
  • Cross-platform problems can occur if different providers with different default values for mode and padding are involved.
  • Explicit specification of mode and padding improves readability.

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?.

Topaco
  • 40,594
  • 4
  • 35
  • 62