Chapter 2 of 8 · 3 checks · 2 min
Cryptography (MASVS-CRYPTO)
Checks that the app uses platform cryptography correctly, with keys generated and held by the platform rather than written into code.
Encryption keys are generated on the device or fetched, never hardcodedMust
Why it matters and how to check
A key written into source code is the same in every install and readable by anyone who unpacks the app, so the encryption it provides is close to none. Keys should be generated on the device inside the Android Keystore or the iOS Keychain or Secure Enclave, or derived from something only the user knows.
To verify: search the code for byte arrays, base64 strings or hex strings passed to cipher or key constructors (
SecretKeySpec,CryptoKit,encrypthelpers). Each key should come from a platform key store call, not a literal. Check third-party SDK settings files for embedded keys as well.Only standard, authenticated algorithms are used, with secure randomnessMust
Why it matters and how to check
Custom ciphers, ECB mode, MD5 or SHA-1 for security, and
Math.randomfor tokens all give a false sense of protection. Android's guidance recommends generating keys withSecureRandom, using 256-bit AES where possible, and authenticated modes such as GCM, or HMAC for integrity.To verify: search the code for
AES/ECB,DES,MD5,SHA1,java.util.RandomandMath.randomused for security values. Replace them with AES-GCM, SHA-256 or better, and the platform's secure random generator. Prefer a reviewed library such as Tink (which Android's docs suggest) or CryptoKit over assembling primitives yourself.Example
Kotlin // Android: a Keystore-backed AES-GCM key that never leaves secure hardware val spec = KeyGenParameterSpec.Builder("session_key", KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT) .setBlockModes(KeyProperties.BLOCK_MODE_GCM) .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) .setKeySize(256) .build() val keyGen = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore") keyGen.init(spec) keyGen.generateKey()Keys for sensitive actions are non-exportable and, where needed, require user authenticationShould
Why it matters and how to check
Keys created inside the Android Keystore or the iOS Secure Enclave can be used by the app but not read out, so even a full copy of the app's files does not reveal them. Both platforms can also require the user to authenticate (biometric or device passcode) before a key is used, which ties sensitive actions to the person holding the device.
To verify: review key creation calls for the access control options: on Android,
setUserAuthenticationRequired(true)for keys behind biometric prompts; on iOS, Keychain access control flags such as requiring user presence andThisDeviceOnlyaccessibility for items that must not migrate to another device.