From 802d5270769bb42a505ba4fec05c0617e9f8f057 Mon Sep 17 00:00:00 2001 From: TheDauntless Date: Mon, 24 Jan 2022 07:26:20 -0500 Subject: [PATCH 1/5] First fixes --- Document/0x05e-Testing-Cryptography.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Document/0x05e-Testing-Cryptography.md b/Document/0x05e-Testing-Cryptography.md index 3b69d5e768..761042095f 100644 --- a/Document/0x05e-Testing-Cryptography.md +++ b/Document/0x05e-Testing-Cryptography.md @@ -57,9 +57,9 @@ The following list of recommendations should be considered during app examinatio ### Security provider -Android relies on `provider` to implement Java Security services. That is crucial to ensure secure network communications and secure other functionalities which depend on cryptography. +Android relies on the `java.security.Provider` class to implement Java Security services. These providers are crucial to ensure secure network communications and secure other functionalities which depend on cryptography. -The list of security providers included in Android varies between versions of Android and the OEM-specific builds. Some security provider implementations in older versions are now known to be less secure or vulnerable. Thus, Android applications should not only choose the correct algorithms and provide good configuration, in some cases they should also pay attention to the strength of the implementations in the legacy security providers. +The list of security providers included in Android varies between versions of Android and the OEM-specific builds. Some security provider implementations in older versions are now known to be less secure or vulnerable. Thus, Android applications should not only choose the correct algorithms and provide a good configuration, in some cases they should also pay attention to the strength of the implementations in the legacy security providers. You can list the set of existing security providers using following code: @@ -78,7 +78,7 @@ String providers = builder.toString(); //now display the string on the screen or in the logs for debugging. ``` -Below you can find the output of a running Android 4.4 (API level 19) in an emulator with Google Play APIs, after the security provider has been patched: +Below you can find the output of a running this snippet on Android 4.4 (API level 19) in an emulator with Google Play APIs, after the security provider has been patched: ```default provider: GmsCore_OpenSSL1.0 (Android's OpenSSL-backed security provider) @@ -90,7 +90,7 @@ provider: HarmonyJSSE1.0 (Harmony JSSE Provider) provider: AndroidKeyStore1.0 (Android AndroidKeyStore security provider) ``` -Below you can find the output of a running Android 9 (API level 28) in an emulator with Google Play APIs: +Below you can find the output of running this snippet on Android 9 (API level 28) in an emulator with Google Play APIs: ```default provider: AndroidNSSP 1.0(Android Network Security Policy Provider) @@ -104,7 +104,7 @@ provider: AndroidKeyStore 1.0(Android KeyStore security provider) #### Updating security provider -Keeping up-to-date and patched component is one of security principles. The same applies to `provider`. Application should check if used security provider is up-to-date and if not, [update it](https://developer.android.com/training/articles/security-gms-provider "Updating security provider"). It is related to [Checking for Weaknesses in Third Party Libraries (MSTG-CODE-5)](0x05i-Testing-Code-Quality-and-Build-Settings.md#checking-for-weaknesses-in-third-party-libraries). +Making sure all security critical components are up-to-date is an important security principle, and security providers are no exception. Applications should check if the installed Provider is up-to-date and [force an update](https://developer.android.com/training/articles/security-gms-provider "Updating security provider") if they aren't. Note that this is only possible on devices that have Google Play services isntalled. #### Older Android versions From af2f95624c89a43e35e53e330ac20f3e418acf33 Mon Sep 17 00:00:00 2001 From: TheDauntless Date: Mon, 24 Jan 2022 13:46:53 -0500 Subject: [PATCH 2/5] Some more fixes --- Document/0x05e-Testing-Cryptography.md | 56 +++++++++++++------------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/Document/0x05e-Testing-Cryptography.md b/Document/0x05e-Testing-Cryptography.md index cd9cc794e3..754c0cf87a 100644 --- a/Document/0x05e-Testing-Cryptography.md +++ b/Document/0x05e-Testing-Cryptography.md @@ -108,13 +108,13 @@ Making sure all security critical components are up-to-date is an important secu #### Older Android versions -For some applications that support older versions of Android (e.g.: only used versions lower than Android 7.0 (API level 24)), bundling an up-to-date library may be the only option. Spongy Castle (a repackaged version of Bouncy Castle) is a common choice in these situations. Repackaging is necessary because Bouncy Castle is included in the Android SDK. The latest version of [Spongy Castle](https://rtyley.github.io/spongycastle/ "Spongy Castle") likely fixes issues encountered in the earlier versions of [Bouncy Castle](https://www.cvedetails.com/vulnerability-list/vendor_id-7637/Bouncycastle.html "CVE Details Bouncy Castle") that were included in Android. Note that the Bouncy Castle libraries packed with Android are often not as complete as their counterparts from the [legion of the Bouncy Castle](https://www.bouncycastle.org/java.html "Bouncy Castle in Java"). Lastly: bear in mind that packing large libraries such as Spongy Castle will often lead to a multidexed Android application. +For some applications that support older versions of Android (e.g.: only used versions lower than Android 7.0 (API level 24)), bundling an up-to-date library may be the only option. Spongy Castle (a repackaged version of Bouncy Castle) is a common choice in these situations. Repackaging is necessary because Bouncy Castle is included in the Android SDK. The latest version of [Spongy Castle](https://rtyley.github.io/spongycastle/ "Spongy Castle") likely fixes issues encountered in the earlier versions of [Bouncy Castle](https://www.cvedetails.com/vulnerability-list/vendor_id-7637/Bouncycastle.html "CVE Details Bouncy Castle") that were included in Android. Note that the Bouncy Castle libraries packed with Android are often not as complete as their counterparts from the [legion of the Bouncy Castle](https://www.bouncycastle.org/java.html "Bouncy Castle in Java"). ### Key Generation -Android SDK provides mechanisms for specifying secure key generation and use. Android 6.0 (API level 23) introduced the `KeyGenParameterSpec` class that can be used to ensure the correct key usage in the application. +The Android SDK allows you to specify how a key should be generated, and under which circumstances it can be used. Android 6.0 (API level 23) introduced the `KeyGenParameterSpec` class that can be used to ensure the correct key usage in the application. -Here's an example of using AES/CBC/PKCS7Padding on API 23+: +The following example shows key generation for AES/CBC/PKCS7Padding on API 23+: ```java String keyAlias = "MySecretKey"; @@ -133,9 +133,9 @@ keyGenerator.init(keyGenParameterSpec); SecretKey secretKey = keyGenerator.generateKey(); ``` -The `KeyGenParameterSpec` indicates that the key can be used for encryption and decryption, but not for other purposes, such as signing or verifying. It further specifies the block mode (CBC), padding (PKCS #7), and explicitly specifies that randomized encryption is required (this is the default). `"AndroidKeyStore"` is the name of security provider used in this example. This will automatically ensure that the keys are stored in the `AndroidKeyStore` which is beneficiary for the protection of the key. +The `KeyGenParameterSpec` indicates that the key can be used for encryption and decryption, but not for other purposes, such as signing or verifying. It further specifies the block mode (CBC), padding (PKCS #7), and explicitly specifies that randomized encryption is required (this is the default). Next, we give `AndroidKeyStore` as the name of the provider in the `KeyGenerator.getInstance` call. This will automatically ensure that the keys are stored in the `AndroidKeyStore` which is beneficiary for the protection of the key. -GCM is another AES block mode that provides additional security benefits over other, older modes. In addition to being cryptographically more secure, it also provides authentication. When using CBC (and other modes), authentication would need to be performed separately, using HMACs (see the "[Tampering and Reverse Engineering on Android](0x05c-Reverse-Engineering-and-Tampering.md)" chapter). Note that GCM is the only mode of AES that [does not support paddings](https://developer.android.com/training/articles/keystore.html#SupportedCiphers "Supported Ciphers in AndroidKeyStore"). +GCM is another AES block mode that provides additional security benefits over other, older modes. In addition to being cryptographically more secure, it also provides authentication. When using CBC (and other modes), authentication would need to be performed separately, using HMACs (see the "[Tampering and Reverse Engineering on Android](0x05c-Reverse-Engineering-and-Tampering.md)" chapter). Note that GCM is the only mode of AES that [does not support padding](https://developer.android.com/training/articles/keystore.html#SupportedCiphers "Supported Ciphers in AndroidKeyStore"). Attempting to use the generated key in violation of the above spec would result in a security exception. @@ -222,19 +222,17 @@ public static SecretKey generateStrongAESKey(char[] password, int keyLength) } ``` -The above method requires a character array containing the password and the needed key length in bits, for instance a 128 or 256-bit AES key. We define an iteration count of 10,000 rounds which will be used by the PBKDF2 algorithm. Increasing number of iteration significantly increases the workload for a brute-force attack on password, however it can affect performance as more computational power is required for key derivation. We define the salt size equal to the key length, we divide by 8 to take care of the bit to byte conversion. We use the `SecureRandom` class to randomly generate a salt. Obviously, the salt is something you want to keep constant to ensure the same encryption key is generated time after time for the same supplied password. Note that you can store the salt privately in `SharedPreferences`. It is recommended to exclude the salt from the Android backup mechanism to prevent synchronization in case of higher risk data. +The above method requires a character array containing the password and the needed key length in bits, for instance a 128 or 256-bit AES key. We define an iteration count of 10,000 rounds which will be used by the PBKDF2 algorithm. Increasing the number of iterations significantly increases the workload for a brute-force attack on the password, however it can affect performance as more computational power is required for key derivation. We define the salt size equal to the key length divided by 8 in order to convert from bits to bytes and we use the `SecureRandom` class to randomly generate a salt. The salt needs to be kept constant to ensure the same encryption key is generated time after time for the same supplied password. Note that you can store the salt privately in `SharedPreferences`. It is recommended to exclude the salt from the Android backup mechanism to prevent synchronization in case of higher risk data. -> Note that if you take a rooted device or a patched (e.g. repackaged) application into account as a threat to the data, it might be better to encrypt the salt with a key that is placed in the `AndroidKeystore`. The Password-Based Encryption (PBE) key is generated using the recommended `PBKDF2WithHmacSHA1` algorithm, till Android 8.0 (API level 26). For higher API levels, it is best to use `PBKDF2withHmacSHA256`, which will end up with a longer hash value. +> Note that if you take a rooted device or a patched (e.g. repackaged) application into account as a threat to the data, it might be better to encrypt the salt with a key that is placed in the `AndroidKeystore`. The Password-Based Encryption (PBE) key is generated using the recommended `PBKDF2WithHmacSHA1` algorithm, until Android 8.0 (API level 26). For higher API levels, it is best to use `PBKDF2withHmacSHA256`, which will end up with a longer hash value. -Note: there is a widespread false believe that the NDK should be used to hide cryptographic operations and hardcoded keys. However, using this mechanism is not effective. Attackers can still use tools to find the mechanism used and make dumps of the key in memory. Next, the control flow can be analyzed with e.g. radare2 and the keys extracted with the help of Frida or the combination of both: [r2frida](0x08-Testing-Tools.md#r2frida) (see sections "[Disassembling Native Code](0x05c-Reverse-Engineering-and-Tampering.md#disassembling-native-code "Disassembling Native Code")", "[Memory Dump](0x05c-Reverse-Engineering-and-Tampering.md#memory-dump "Memory Dump")" and "[In-Memory Search](0x05c-Reverse-Engineering-and-Tampering.md#in-memory-search "In-Memory Search")" in the chapter "Tampering and Reverse Engineering on Android" for more details). From Android 7.0 (API level 24) onward, it is not allowed to use private APIs, instead: public APIs need to be called, which further impacts the effectiveness of hiding it away as described in the [Android Developers Blog](https://android-developers.googleblog.com/2016/06/android-changes-for-ndk-developers.html "Android changes for NDK developers") +Note: there is a widespread false believe that the NDK should be used to hide cryptographic operations and hardcoded keys. However, using this mechanism is not effective. Attackers can still use tools to find the used mechanism and extract the key from memory. For example, the control flow can be analyzed with e.g. radare2 and the keys can be extracted with the help of Frida: [r2frida](0x08-Testing-Tools.md#r2frida) (see sections "[Disassembling Native Code](0x05c-Reverse-Engineering-and-Tampering.md#disassembling-native-code "Disassembling Native Code")", "[Memory Dump](0x05c-Reverse-Engineering-and-Tampering.md#memory-dump "Memory Dump")" and "[In-Memory Search](0x05c-Reverse-Engineering-and-Tampering.md#in-memory-search "In-Memory Search")" in the chapter "Tampering and Reverse Engineering on Android" for more details). From Android 7.0 (API level 24) onward, it is not allowed to use private APIs, instead: public APIs need to be called, which further impacts the effectiveness of hiding it away as described in the [Android Developers Blog](https://android-developers.googleblog.com/2016/06/android-changes-for-ndk-developers.html "Android changes for NDK developers") ### Random number generation Cryptography requires secure pseudo random number generation (PRNG). Standard Java classes as `java.util.Random` do not provide sufficient randomness and in fact may make it possible for an attacker to guess the next value that will be generated, and use this guess to impersonate another user or access sensitive information. -In general, `SecureRandom` should be used. However, if the Android versions below Android 4.4 (API level 19) are supported, additional care needs to be taken in order to work around the bug in Android 4.1-4.3 (API level 16-18) versions that [failed to properly initialize the PRNG](https://android-developers.googleblog.com/2013/08/some-securerandom-thoughts.html "Some SecureRandom Thoughts"). - -Most developers should instantiate `SecureRandom` via the default constructor without any arguments. Other constructors are for more advanced uses and, if used incorrectly, can lead to decreased randomness and security. The PRNG provider backing `SecureRandom` uses the `SHA1PRNG` from `AndroidOpenSSL` (Conscrypt) provider. +A secure PRNG is available as `java.security.SecureRandom`. Most developers should instantiate `SecureRandom` via the default constructor without any arguments. Other constructors are for more advanced uses and, if used incorrectly, can lead to decreased randomness and security. The PRNG provider backing `SecureRandom` uses the `SHA1PRNG` from `AndroidOpenSSL` (Conscrypt) provider. ## Testing Symmetric Cryptography (MSTG-CRYPTO-1) @@ -260,17 +258,17 @@ For each identified instance verify if the used symmetric keys: - cannot be derived from known values - are not hardcoded in code -For each hardcoded symmetric key, verify that is not used in security-sensitive contexts as the only method of encryption. +For each hardcoded symmetric key, verify that it is not used in security-sensitive contexts as the only method of encryption. As an example we illustrate how to locate the use of a hardcoded encryption key. First [disassemble and decompile](0x05c-Reverse-Engineering-and-Tampering.md#disassembling-and-decompiling) the app to obtain Java code, e.g. by using [jadx](0x08-Testing-Tools.md#jadx). -Now search the files for the usage of the `SecretKeySpec` class, e.g. by simply recursively grepping on them or using jadx search function: +Now search the files for the usage of the `SecretKeySpec` class, e.g. by simply recursively grepping on the decompiled code: ```bash $ grep -r "SecretKeySpec" ``` -This will return all classes using the `SecretKeySpec` class. Now examine those files and trace which variables are used to pass the key material. The figure below shows the result of performing this assessment on a production ready application. We can clearly locate the use of a static encryption key that is hardcoded and initialized in the static byte array `Encrypt.keyBytes`. +This will return all classes using the `SecretKeySpec` class. Now examine those files and trace which variables are used to pass the key material. The image below shows the result of performing this assessment on a production ready application. We can clearly locate the use of a static encryption key that is hardcoded and initialized in the static byte array `Encrypt.keyBytes`. @@ -278,15 +276,19 @@ This will return all classes using the `SecretKeySpec` class. Now examine those You can use [method tracing](0x05c-Reverse-Engineering-and-Tampering.md#method-tracing) on cryptographic methods to determine input / output values such as the keys that are being used. Monitor file system access while cryptographic operations are being performed to assess where key material is written to or read from. For example, monitor the file system by using the [API monitor](https://github.com/m0bilesecurity/RMS-Runtime-Mobile-Security#8-api-monitor---android-only) of [RMS - Runtime Mobile Security](0x08-Testing-Tools.md#RMS-Runtime-Mobile-Security). -## Testing the Configuration of Cryptographic Standard Algorithms (MSTG-CRYPTO-2, MSTG-CRYPTO-3 and MSTG-CRYPTO-4) +## Testing the usage of proven implementations of cryptographic primitives (MSTG-CRYPTO-2) + +## Testing the Configuration of Cryptographic Standard Algorithms (MSTG-CRYPTO-3) + +## Testing the usage of cryptographic protocols and algorithms (MSTG-CRYPTO-4) ### Overview These test cases focus on implementation and use of cryptographic primitives. Following checks should be performed: -- identify all instance of cryptography primitives and their implementation (library or custom implementation) -- verify how cryptography primitives are used and how they are configured -- verify if cryptographic protocols and algorithms used are not deprecated for security purposes. +- identify all instance of cryptographic primitives and their implementation (library or custom implementation) +- verify how cryptographic primitives are used and how they are configured +- verify if used cryptographic protocols and algorithms are not deprecated for security purposes. ### Static Analysis @@ -298,9 +300,9 @@ Identify all the instances of the cryptographic primitives in code. Identify all - exceptions `KeyStoreException`, `CertificateException`, `NoSuchAlgorithmException` - classes which uses `java.security.*`, `javax.crypto.*`, `android.security.*` and `android.security.keystore.*` packages. -Identify that all calls to getInstance use default `provider` of security services by not specifying it (it means AndroidOpenSSL aka Conscrypt). `Provider` can only be specified in `KeyStore` related code (in that situation `KeyStore` should be provided as `provider`). If other `provider` is specified it should be verified according to situation and business case (i.e. Android API version), and `provider` should be examined against potential vulnerabilities. +Identify that all calls to getInstance use the default `provider` of security services by not specifying it (it will default to AndroidOpenSSL aka Conscrypt). `Provider` can only be specified in `KeyStore` related code (in that situation `KeyStore` should be provided as `provider`). If another `provider` is specified it should be verified according to the usage and business case (i.e. Android API version), and the `provider` should be examined against potential vulnerabilities. -Ensure that the best practices outlined in the "[Cryptography for Mobile Apps](0x04g-Testing-Cryptography.md)" chapter are followed. Look at [insecure and deprecated algorithms](0x04g-Testing-Cryptography.md#identifying-insecure-and/or-deprecated-cryptographic-algorithms) and [common configuration issues](0x04g-Testing-Cryptography.md#common-configuration-issues). +Ensure that the best practices outlined in the "[Cryptography for Mobile Apps](0x04g-Testing-Cryptography.md)" chapter are followed. Look at [insecure and deprecated algorithms](0x04g-Testing-Cryptography.md#identifying-insecure-and/or-deprecated-cryptographic-algorithms) and [common configuration issues](0x04g-Testing-Cryptography.md#common-configuration-issues) for more information. ### Dynamic Analysis @@ -333,12 +335,12 @@ For each identified instance, identify its purpose and its type. It can be used: - for signing/verifying - to ensure integrity of data (as well as accountability in some cases) - for maintenance - to protect keys during certain sensitive operations (such as being imported to the KeyStore) -Additionally, you should identify the business logic which uses identified instances of cryptography. +Additionally, you should identify the business logic which uses any identified instances of cryptography. During verification the following checks should be performed: -- are all keys used according to the purpose defined during its creation? (it is relevant to KeyStore keys, which can have KeyProperties defined) -- for asymmetric keys, is the private key being exclusively used for signing and the public key encryption? +- are all keys used according to the purpose defined during their creation? (it is relevant to KeyStore keys, which can have KeyProperties defined) +- for asymmetric keys, is the private key only used for signing, while the public key is only used for encryption? - are symmetric keys used for multiple purposes? A new symmetric key should be generated if it's used in a different context. - is cryptography used according to its business purpose? @@ -350,10 +352,10 @@ You can use [method tracing](0x05c-Reverse-Engineering-and-Tampering.md#method-t ### Overview -This test case focuses on random values used by application. The following checks should be performed: +This test case focuses on random values used by an application. The following checks should be performed: - identify all instances where random values are used -- verify if random number generators are not considered as being cryptographically secure +- verify if any random number generator is not considered as being cryptographically secure - verify how random number generators are used - verify randomness of the generated random values @@ -361,14 +363,14 @@ This test case focuses on random values used by application. The following check Identify all the instances of random number generators and look for either custom or well-known insecure classes. For instance, `java.util.Random` produces an identical sequence of numbers for each given seed value; consequently, the sequence of numbers is predictable. Instead a well-vetted algorithm should be chosen that is currently considered to be strong by experts in the field, and a well-tested implementations with adequate length seeds should be used. -Identify all instances of `SecureRandom` that are not created using the default constructor. Specifying the seed value may reduce randomness. Prefer the [no-argument constructor of `SecureRandom`](https://www.securecoding.cert.org/confluence/display/java/MSC02-J.+Generate+strong+random+numbers "Generation of Strong Random Numbers") that uses the system-specified seed value to generate a 128-byte-long random number. +Identify all instances of `SecureRandom` that are not created using the default constructor, since specifying the seed value may reduce randomness. Prefer the [no-argument constructor of `SecureRandom`](https://www.securecoding.cert.org/confluence/display/java/MSC02-J.+Generate+strong+random+numbers "Generation of Strong Random Numbers") that uses the system-specified seed value to generate a 128-byte-long random number. In general, if a PRNG is not advertised as being cryptographically secure (e.g. `java.util.Random`), then it is probably a statistical PRNG and should not be used in security-sensitive contexts. Pseudo-random number generators [can produce predictable numbers](https://www.securecoding.cert.org/confluence/display/java/MSC63-J.+Ensure+that+SecureRandom+is+properly+seeded "Proper seeding of SecureRandom") if the generator is known and the seed can be guessed. A 128-bit seed is a good starting point for producing a "random enough" number. Once an attacker knows what type of weak pseudo-random number generator (PRNG) is used, it can be trivial to write a proof-of-concept to generate the next random value based on previously observed ones, as it was [done for Java Random](https://franklinta.com/2014/08/31/predicting-the-next-math-random-in-java/ "Predicting the next Math.random() in Java"). In case of very weak custom random generators it may be possible to observe the pattern statistically. Although the recommended approach would anyway be to decompile the APK and inspect the algorithm (see Static Analysis). -If you want to test for randomness, you can try to capture a large set of numbers and check with the Burp's [sequencer](https://portswigger.net/burp/documentation/desktop/tools/sequencer "Burp\'s Sequencer") to see how good the quality of the randomness is. +If you want to test for randomness, you can try to capture a large set of numbers and check with Burp's [sequencer](https://portswigger.net/burp/documentation/desktop/tools/sequencer "Burp\'s Sequencer") to see how good the quality of the randomness is. ### Dynamic Analysis From 41838509de8a106a8293c2a4a5ec6312169bc92e Mon Sep 17 00:00:00 2001 From: TheDauntless Date: Mon, 24 Jan 2022 14:44:00 -0500 Subject: [PATCH 3/5] Revert split --- Document/0x05e-Testing-Cryptography.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Document/0x05e-Testing-Cryptography.md b/Document/0x05e-Testing-Cryptography.md index 754c0cf87a..50ae8b6267 100644 --- a/Document/0x05e-Testing-Cryptography.md +++ b/Document/0x05e-Testing-Cryptography.md @@ -276,11 +276,7 @@ This will return all classes using the `SecretKeySpec` class. Now examine those You can use [method tracing](0x05c-Reverse-Engineering-and-Tampering.md#method-tracing) on cryptographic methods to determine input / output values such as the keys that are being used. Monitor file system access while cryptographic operations are being performed to assess where key material is written to or read from. For example, monitor the file system by using the [API monitor](https://github.com/m0bilesecurity/RMS-Runtime-Mobile-Security#8-api-monitor---android-only) of [RMS - Runtime Mobile Security](0x08-Testing-Tools.md#RMS-Runtime-Mobile-Security). -## Testing the usage of proven implementations of cryptographic primitives (MSTG-CRYPTO-2) - -## Testing the Configuration of Cryptographic Standard Algorithms (MSTG-CRYPTO-3) - -## Testing the usage of cryptographic protocols and algorithms (MSTG-CRYPTO-4) +## Testing the Configuration of Cryptographic Standard Algorithms (MSTG-CRYPTO-2, MSTG-CRYPTO-3 and MSTG-CRYPTO-4) ### Overview From b24582c3a8deaa0bea29659c9cd25209a965704e Mon Sep 17 00:00:00 2001 From: Carlos Holguera Date: Sat, 29 Jul 2023 09:37:24 +0200 Subject: [PATCH 4/5] minor fix --- Document/0x05e-Testing-Cryptography.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Document/0x05e-Testing-Cryptography.md b/Document/0x05e-Testing-Cryptography.md index b177aad696..32b0f7720c 100644 --- a/Document/0x05e-Testing-Cryptography.md +++ b/Document/0x05e-Testing-Cryptography.md @@ -7,13 +7,13 @@ platform: android ## Overview -In the chapter ["Mobile App Cryptography"](0x04g-Testing-Cryptography.md), 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 linked from this guide. +In the chapter ["Mobile App Cryptography"](0x04g-Testing-Cryptography.md), 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 in Android: +We can identify key components of cryptography system on Android: - [Security Provider](0x05e-Testing-Cryptography.md#security-provider) -- KeyStore - see the section [KeyStore](0x05d-Testing-Data-Storage.md#keystore) in the chapter "Testing Data Storage" -- KeyChain - see the section [KeyChain](0x05d-Testing-Data-Storage.md#keychain) in the chapter "Testing Data Storage" +- KeyStore - see the section [KeyStore](0x05d-Testing-Data-Storage.md#keystore) in the "Testing Data Storage" chapter +- KeyChain - see the section [KeyChain](0x05d-Testing-Data-Storage.md#keychain) in the "Testing Data Storage" chapter 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](https://developer.android.com/reference/java/security/Provider.html "Android 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.*`. From 609c4264fe42f5c7a519e67846523e4841721a66 Mon Sep 17 00:00:00 2001 From: Carlos Holguera Date: Sat, 29 Jul 2023 11:18:24 +0200 Subject: [PATCH 5/5] minor fixes --- Document/0x05e-Testing-Cryptography.md | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/Document/0x05e-Testing-Cryptography.md b/Document/0x05e-Testing-Cryptography.md index 32b0f7720c..d02bad30ba 100644 --- a/Document/0x05e-Testing-Cryptography.md +++ b/Document/0x05e-Testing-Cryptography.md @@ -85,19 +85,7 @@ String providers = builder.toString(); //now display the string on the screen or in the logs for debugging. ``` -Below you can find the output of a running this snippet on Android 4.4 (API level 19) in an emulator with Google Play APIs, after the security provider has been patched: - -```default -provider: GmsCore_OpenSSL1.0 (Android's OpenSSL-backed security provider) -provider: AndroidOpenSSL1.0 (Android's OpenSSL-backed security provider) -provider: DRLCertFactory1.0 (ASN.1, DER, PkiPath, PKCS7) -provider: BC1.49 (BouncyCastle Security Provider v1.49) -provider: Crypto1.0 (HARMONY (SHA1 digest; SecureRandom; SHA1withDSA signature)) -provider: HarmonyJSSE1.0 (Harmony JSSE Provider) -provider: AndroidKeyStore1.0 (Android AndroidKeyStore security provider) -``` - -Below you can find the output of running this snippet on Android 9 (API level 28) in an emulator with Google Play APIs: +This is the output for Android 9 (API level 28) running in an emulator with Google Play APIs: ```default provider: AndroidNSSP 1.0(Android Network Security Policy Provider) @@ -133,9 +121,7 @@ Security.addProvider(Conscrypt.newProvider()) ### Key Generation -The Android SDK allows you to specify how a key should be generated, and under which circumstances it can be used. Android 6.0 (API level 23) introduced the `KeyGenParameterSpec` class that can be used to ensure the correct key usage in the application. - -The following example shows key generation for AES/CBC/PKCS7Padding on API 23+: +The Android SDK allows you to specify how a key should be generated, and under which circumstances it can be used. Android 6.0 (API level 23) introduced the `KeyGenParameterSpec` class that can be used to ensure the correct key usage in the application. For example: ```java String keyAlias = "MySecretKey"; @@ -154,7 +140,7 @@ keyGenerator.init(keyGenParameterSpec); SecretKey secretKey = keyGenerator.generateKey(); ``` -The `KeyGenParameterSpec` indicates that the key can be used for encryption and decryption, but not for other purposes, such as signing or verifying. It further specifies the block mode (CBC), padding (PKCS #7), and explicitly specifies that randomized encryption is required (this is the default). Next, we give `AndroidKeyStore` as the name of the provider in the `KeyGenerator.getInstance` call. This will automatically ensure that the keys are stored in the `AndroidKeyStore` which is beneficiary for the protection of the key. +The `KeyGenParameterSpec` indicates that the key can be used for encryption and decryption, but not for other purposes, such as signing or verifying. It further specifies the block mode (CBC), padding (PKCS #7), and explicitly specifies that randomized encryption is required (this is the default). Next, we enter `AndroidKeyStore` as the name of the provider in the `KeyGenerator.getInstance` call to ensure that the keys are stored in the Android KeyStore. GCM is another AES block mode that provides additional security benefits over other, older modes. In addition to being cryptographically more secure, it also provides authentication. When using CBC (and other modes), authentication would need to be performed separately, using HMACs (see the "[Tampering and Reverse Engineering on Android](0x05c-Reverse-Engineering-and-Tampering.md)" chapter). Note that GCM is the only mode of AES that [does not support padding](https://developer.android.com/training/articles/keystore.html#SupportedCiphers "Supported Ciphers in AndroidKeyStore").