Android Cryptographic APIs¶
Overview¶
In the chapter "Mobile App Cryptography", we introduced general cryptography best practices and described typical issues that can occur when cryptography is used incorrectly. In this chapter, we'll go into more detail on Android's cryptography APIs. We'll show how to identify usage of those APIs in the source code and how to interpret cryptographic configurations. When reviewing code, make sure to compare the cryptographic parameters used with the current best practices, as linked in this guide.
We can identify key components of cryptography system on Android:
Android cryptography APIs are based on the Java Cryptography Architecture (JCA). JCA separates the interfaces and implementation, making it possible to include several security providers that can implement sets of cryptographic algorithms. Most of the JCA interfaces and classes are defined in the java.security.*
and javax.crypto.*
packages. In addition, there are Android specific packages android.security.*
and android.security.keystore.*
.
KeyStore and KeyChain provide APIs for storing and using keys (behind the scene, KeyChain API uses KeyStore system). These systems allow to administer the full lifecycle of the cryptographic keys. Requirements and guidance for implementation of cryptographic key management can be found in Key Management Cheat Sheet. We can identify following phases:
- generating a key
- using a key
- storing a key
- archiving a key
- deleting a key
Please note that storing of a key is analyzed in the chapter "Testing Data Storage".
These phases are managed by the Keystore/KeyChain system. However how the system works depends on how the application developer implemented it. For the analysis process you should focus on functions which are used by the application developer. You should identify and verify the following functions:
- Key Generation
- Random number generation
- Key rotation
Apps that target modern API levels, went through the following changes:
- For Android 7.0 (API level 24) and above the Android Developer blog shows that:
- It is recommended to stop specifying a security provider. Instead, always use a patched Security Provider.
- The support for the
Crypto
provider has dropped and the provider is deprecated. The same applies to itsSHA1PRNG
for secure random.
- For Android 8.1 (API level 27) and above the Developer Documentation shows that:
- Conscrypt, known as
AndroidOpenSSL
, is preferred above using Bouncy Castle and it has new implementations:AlgorithmParameters:GCM
,KeyGenerator:AES
,KeyGenerator:DESEDE
,KeyGenerator:HMACMD5
,KeyGenerator:HMACSHA1
,KeyGenerator:HMACSHA224
,KeyGenerator:HMACSHA256
,KeyGenerator:HMACSHA384
,KeyGenerator:HMACSHA512
,SecretKeyFactory:DESEDE
, andSignature:NONEWITHECDSA
. - You should not use the
IvParameterSpec.class
anymore for GCM, but use theGCMParameterSpec.class
instead. - Sockets have changed from
OpenSSLSocketImpl
toConscryptFileDescriptorSocket
, andConscryptEngineSocket
. SSLSession
with null parameters give aNullPointerException
.- You need to have large enough arrays as input bytes for generating a key otherwise, an
InvalidKeySpecException
is thrown. - If a Socket read is interrupted, you get a
SocketException
.
- Conscrypt, known as
- For Android 9 (API level 28) and above the Android Developer Blog shows even more changes:
- You get a warning if you still specify a security provider using the
getInstance
method and you target any API below 28. If you target Android 9 (API level 28) or above, you get an error. - The
Crypto
security provider is now removed. Calling it will result in aNoSuchProviderException
.
- You get a warning if you still specify a security provider using the
- For Android 10 (API level 29) the Developer Documentation lists all network security changes.
General Recommendations:
The following list of recommendations should be considered during app examination:
- You should ensure that the best practices outlined in the "Cryptography for Mobile Apps" chapter are followed.
- You should ensure that security provider has the latest updates - Updating security provider.
- You should stop specifying a security provider and use the default implementation (AndroidOpenSSL, Conscrypt).
- You should stop using Crypto security provider and its
SHA1PRNG
as they are deprecated. - You should specify a security provider only for the Android Keystore system.
- You should stop using Password-based encryption ciphers without IV.
- You should use KeyGenParameterSpec instead of KeyPairGeneratorSpec.
Knowledge Articles¶
ID | Name | Platform |
---|---|---|
MASTG-KNOW-0011 | Security Provider | |
MASTG-KNOW-0012 | Key Generation | |
MASTG-KNOW-0013 | Random number generation |