Join our Newsletter — 33% off our NHI Course
Home› Guides› OWASP Mobile Top 10 M10 Insufficient Cryptography Guide:…
Guide Application Security

OWASP Mobile Top 10 M10 Insufficient Cryptography Guide: Using Platform Crypto Correctly

PDF for newsletter subscribers · free to read online

← All guides
By NHI Mgmt Group, edited by Lalit Choda Updated 26 October 2026 14 min read
On this page

Most mobile cryptography failures are not broken algorithms but sound algorithms used badly: a key compiled into the app, a static IV, a fallback to SHA-1, or a password hashed once with no salt. M10 Insufficient Cryptography is the tenth risk in the OWASP Mobile Top 10 2024, and it matters more on mobile than on servers because the attacker can hold the device and the binary at the same time. This guide goes deeper than the OWASP Mobile Top 10 Guide: it covers what M10 and the MASVS-CRYPTO controls require, how to use Android Keystore and the Apple Secure Enclave and CryptoKit correctly, how to test and evidence the controls, and where keys used by the app count as non-human identities. It is written for mobile developers, application security engineers and testers working to MASVS.

Key takeaways

  • Use the platform, not your own crypto. Android's JCA providers with Android Keystore and Apple CryptoKit with the Keychain and Secure Enclave already implement current algorithms; custom schemes and third-party providers are where most M10 findings start.
  • Keys are the real target. A strong cipher with a key stored in the APK, IPA or shared preferences protects nothing, because every copy of the app ships the same key.
  • Hardware-backed and non-exportable by default. Generate keys inside Android Keystore (TEE or StrongBox) or the Secure Enclave, bind them to a purpose and, where it fits, to user authentication.
  • Authenticated encryption and proper randomness. AES-GCM or ChaCha20-Poly1305 with a unique nonce per message, a CSPRNG for every key, IV and token, and no ECB, MD5 or SHA-1 for security decisions.
  • Passwords are hashed, not encrypted. Server-side, use Argon2id, scrypt, bcrypt or PBKDF2 with OWASP parameters; on the device, avoid storing passwords at all and keep tokens in hardware-protected storage instead.

What it is and who it applies to

OWASP describes M10 as the use of weak or outdated algorithms, short or guessable keys, insecure key storage or transmission, flawed implementations, partial encryption of sensitive data and missing or weak salting of password hashes. OWASP rates it as average exploitability, common prevalence, average detectability and severe impact. The official risk name, "M10: Insufficient Cryptography", matches this guide's title.

It applies to any Android or iOS app (native, Flutter, React Native, Xamarin or .NET MAUI) that encrypts, signs, hashes or derives keys on the device, and to the backend services whose design decides what the device must protect. Typical scope:

  • Local data protection: encrypted databases, cached documents, offline tokens and files written outside the platform's protected storage.
  • Message-level crypto: payload signing, request MACs, end-to-end encryption in messaging and payment apps.
  • Integrity checks: verifying downloaded content, configuration or update packages by signature.
  • Derived keys: keys built from PINs, passwords or biometrics, where KDF choice and parameters decide brute-force cost.

Transport security (TLS configuration, pinning) is mainly covered by M5; see the OWASP Mobile Top 10 M5 Insecure Communication Guide. Where data sits on the device is M9; see the OWASP Mobile Top 10 M9 Insecure Data Storage Guide. M10 is about whether the cryptography inside those choices is sound.

Structure and key requirements

OWASP MASVS turns M10 into two controls. MASVS-CRYPTO-1: "The app employs current strong cryptography and uses it according to industry best practices." MASVS-CRYPTO-2: "The app performs key management according to industry best practices." The MASVS points to NIST SP 800-175B and SP 800-57 as the external standards. The OWASP Mobile Application Security Weakness Enumeration (MASWE) breaks these into testable weaknesses.

MASWEWeaknessWhat a tester looks forControl
MASWE-0007Improper EncryptionECB mode, DES or 3DES for new data, static or zero IVs, unauthenticated CBCCRYPTO-1
MASWE-0008Improper HashingMD5 or SHA-1 for integrity or passwords, unsalted hashesCRYPTO-1
MASWE-0009Improper Use of Message Authentication Code (MAC)Hash used in place of HMAC, non-constant-time comparisonCRYPTO-1
MASWE-0010 / 0011Improper Generation / Verification of Cryptographic SignatureWeak signature schemes, signature result ignored or verification skipped on errorCRYPTO-1
MASWE-0012Improper Random Number Generationjava.util.Random, Math.random(), seeded or time-based generators for keys, IVs or tokensCRYPTO-1
MASWE-0013Improper Cryptographic Key GenerationShort keys, keys generated outside the Keystore or Secure EnclaveCRYPTO-2
MASWE-0014Improper Cryptographic Key DerivationSingle-pass hash of a PIN, low PBKDF2 iteration counts, static saltsCRYPTO-2
MASWE-0015Cryptographic Key Rotation Not ImplementedNo key versioning, one key for the life of the installCRYPTO-2
MASWE-0016Cryptographic Key Access Not RestrictedKeys usable for any purpose, no authentication bindingCRYPTO-2
MASWE-0017Device Secure Lock Not EnforcedSensitive keys usable on a device with no passcodeCRYPTO-2

Algorithm baseline

Android's cryptography guidance recommends AES in GCM mode with 256-bit keys (AES/GCM/NoPadding) for Cipher, SHA-256 for MessageDigest, HMACSHA256 for Mac and SHA256withECDSA for Signature. Apple asks developers to prefer CryptoKit over lower-level interfaces; it provides AES.GCM, ChaChaPoly, SHA-2 and SHA-3, HMAC, HKDF, P-256/P-384/P-521, Curve25519 and HPKE, and it isolates MD5 and SHA-1 in an explicitly named Insecure namespace.

PurposeUseAvoid
Symmetric encryptionAES-256-GCM, ChaCha20-Poly1305ECB, DES, 3DES, RC4, CBC without a MAC
HashingSHA-256, SHA-384, SHA-512, SHA-3MD5, SHA-1 for any security decision
Message authenticationHMAC-SHA256Plain hash of key plus message
SignaturesECDSA P-256 (SHA256withECDSA), Ed25519, RSA 2048 or largerRSA below 2048 bits, SHA-1 based signatures
Public-key encryptionHPKE, RSA-OAEP with explicit parametersRSA PKCS#1 v1.5 for new designs
Password-derived keysArgon2id, scrypt, PBKDF2-HMAC-SHA256 with OWASP parametersSingle SHA-256 pass, static salt
RandomnessSecureRandom (Android), SystemRandomNumberGenerator or CryptoKit key generation (iOS)java.util.Random, Math.random(), time seeds

Platform specifics that cause findings

  • Provider selection on Android: name a provider only for AndroidKeyStore. Requesting the "BC" provider explicitly uses deprecated implementations, and the "Crypto" provider (SHA1PRNG) was removed in Android 9, throwing NoSuchProviderException.
  • Password-based encryption without an IV: Android assumes a zero IV if none is passed, so every encryption under that key starts identically.
  • RSA-OAEP digests: Android Keystore uses SHA-1 for MGF1 when the transformation string does not set it; pass an explicit OAEPParameterSpec when the server expects SHA-256 for both.
  • Jetpack Security: all APIs in androidx.security:security-crypto (EncryptedSharedPreferences, EncryptedFile) were deprecated in version 1.1.0 with no further releases planned. Plan a migration to direct Keystore-backed encryption rather than starting new work on it.
  • Post-quantum readiness: CryptoKit now exposes ML-KEM (MLKEM768, MLKEM1024), the X-Wing hybrid KEM and ML-DSA (MLDSA65, MLDSA87), some within the Secure Enclave. Build algorithm agility now even if you do not deploy them yet. See the Post-Quantum Cryptography Migration Guide.

Choosing where a key lives

OptionProtectionTrade-offChoose when
Android Keystore, TEE-backedKey material never enters the app process; bound to the TEE where supportedAlgorithm support varies by deviceDefault for every app key
Android StrongBox (API 28+)Embedded Secure Element, stronger tamper resistanceSlower, fewer concurrent operations, limited to RSA 2048, AES 128/256, P-256, HMAC-SHA256 and 3DES; throws StrongBoxUnavailableException when unsupportedBanking, payments and identity apps facing physical attack risk; fall back to TEE if unavailable
Apple Secure Enclave (SecureEnclave.P256)Private key generated and used inside the enclave, not exportableP-256 (and the newer ML-KEM, ML-DSA types) only; wrap symmetric keys with it rather than storing them in itSigning, key agreement, wrapping data keys
Keychain item, ThisDeviceOnly classAES-256-GCM encrypted; backup copy protected by the device UID so it is useless on another deviceKey material is decrypted into app memory when usedStoring wrapped symmetric keys and tokens
Server-side KMS or HSMKey never on the deviceNeeds connectivity and a strong client identityAnything shared across users or installs

Small teams should start with the platform defaults (Keystore TEE keys, CryptoKit with Keychain) and reserve StrongBox and attestation for high-value flows. Large organisations with many apps benefit from a shared crypto wrapper library, reviewed once and used everywhere, which is also how MASWE-0015 rotation and algorithm agility become practical.

Identity and NHI requirements

Every key an app uses to authenticate to something is a non-human identity, and it needs the same lifecycle as any other machine credential. Three cases matter:

  • Shared secrets in the binary: an HMAC key or AES key compiled into the app is identical in every install, so extracting it once compromises every user. The Gladinet case shows the server-side version of the same mistake: the Gladinet Hard-Coded Keys 2025 incident used one fixed AES key and IV across every installation, which let attackers forge access tickets. Research into App Store apps found hard-coded secrets in 71 per cent of the 156,080 apps analysed; see iOS Apps Leaking Hard-Coded Secrets 2025. See the OWASP Mobile Top 10 M1 Improper Credential Usage Guide.
  • Per-install device keys: generate a key pair per install in Keystore or the Secure Enclave, register the public key with the backend and use it for request signing or token binding. On Android, key attestation lets the server check that the key is hardware-backed before trusting it.
  • User-bound keys: where an operation needs a human present (payment approval, viewing secrets), bind the key to biometric or device credential authentication through BiometricPrompt on Android or Keychain access control on iOS, so a stolen unlocked session cannot silently use it.

Treat backend keys that the app uses through an API (encryption keys held in a KMS, signing keys for content) as service identities with owners, rotation dates and revocation paths. See the Cryptographic Key Management Guide.

Implementation steps

  1. Inventory crypto use. Search source and decompiled release binaries for Cipher.getInstance, MessageDigest, Mac, SecretKeySpec, CommonCrypto (CCCrypt), CryptoKit and third-party libraries. Record algorithm, mode, key source and purpose for each call site. ASVS 5.0 V11.1.2 asks for exactly this cryptographic inventory; see the Cryptographic Inventory and CBOM Guide.
  2. Remove keys from the binary first. Any key found in a shipped build must be treated as public. Move it server-side, replace it with per-install keys, and rotate it on the backend.
  3. Introduce a wrapper. Build one internal module per platform that exposes encrypt, decrypt, sign and verify with fixed safe defaults (AES-256-GCM, random 12-byte nonce, Keystore or Secure Enclave keys) and records a key version with every ciphertext.
  4. Generate keys in hardware. On Android use KeyGenParameterSpec with explicit purposes, block modes, paddings and digests; authorisations cannot be changed after creation, so set them correctly at generation. Check KeyInfo.getSecurityLevel() for TRUSTED_ENVIRONMENT or STRONGBOX on API 29+. On iOS use SecureEnclave.P256 keys where SecureEnclave.isAvailable is true and wrap symmetric keys with them.
  5. Bind sensitive keys to authentication and device lock. Use setUserAuthenticationParameters and setUnlockedDeviceRequired on Android, and a ThisDeviceOnly accessibility class with an access control on iOS.
  6. Migrate data in a controlled way. Ship the new scheme in read-old, write-new mode: decrypt legacy data on first access, re-encrypt with the new key version, and keep the old path behind a feature flag for one or two releases so you can roll back if a device class fails.
  7. Pilot by device cohort. Release to a staged rollout percentage and watch for Keystore exceptions (StrongBoxUnavailableException, KeyPermanentlyInvalidatedException after biometric changes) before widening. Rollback is a server flag that switches the app back to the previous wrapper path, never a downgrade to weaker algorithms.
  8. Enforce in CI. Add static rules that fail release builds on ECB, MD5 or SHA-1 for security use, java.util.Random in crypto code, SecretKeySpec built from string literals, and explicit "BC" provider requests. Start in report-only mode for one sprint to clear false positives.

Evidence and assessment

Assess M10 against the binary that ships, not only the source, because build tools, SDKs and obfuscators add crypto calls of their own.

ActivityWhat it provesEvidence to keep
Static analysis of APK, AAB or IPANo hard-coded keys, weak algorithms or insecure RNG in release codeScan report per release, mapped to MASWE IDs
Dynamic instrumentation on a test deviceReal algorithm, mode, IV and key source used at runtimeHooked call traces for each crypto call site
Key property checkKeys are hardware-backed and purpose-restrictedKeyInfo output (security level, purposes, auth enforcement); Android attestation certificate chain
Data at rest reviewSensitive files and databases are encrypted with unique noncesExtracted app container from a test device with ciphertext samples
Manual MASTG-based testControl-level conclusion for MASVS-CRYPTO-1 and -2Signed test report per major release

Metrics

  • Binary key findings: hard-coded keys or secrets found in release builds per quarter (target zero, and every finding rotated within an agreed window).
  • Weak algorithm call sites: count of MD5, SHA-1, ECB, DES or non-CSPRNG uses in security paths, trending to zero.
  • Hardware-backed key ratio: share of app keys reporting TRUSTED_ENVIRONMENT, STRONGBOX or Secure Enclave across the installed base.
  • Wrapper adoption: percentage of crypto call sites going through the approved library.
  • Key rotation coverage: share of keys with a version tag and a tested rotation path.

On the backend, log signature verification failures, unknown key versions and attestation failures per app version; a spike after a release often signals a broken migration, while a steady trickle from one device population can signal tampering. See the Mobile App Security Testing Guide.

Mapping to other frameworks

FrameworkReferenceRelevance to M10
OWASP MASVSMASVS-CRYPTO-1, MASVS-CRYPTO-2The verification controls for M10
OWASP ASVS 5.0V11.1.1, V11.1.2, V11.2.1, V11.3.2, V11.4.2, V11.5.1Key lifecycle policy, crypto inventory, validated implementations, approved modes, password KDFs, CSPRNG with 128 bits of entropy (useful for the backend)
NIST SP 800-53 Rev. 5SC-12, SC-13, SC-28(1)Key establishment and management, cryptographic protection, encryption of data at rest
NIST CSF 2.0PR.DS-01, PR.DS-02Data at rest and data in transit protection
NIST SP 800-131A Rev. 2Algorithm and key length transitionsWhich algorithms and key sizes are acceptable (Rev. 3 is in draft)
CIS Controls v8.13.10, 3.11Encrypt sensitive data in transit and at rest
ISO/IEC 27001:2022Annex A 8.24 Use of cryptographyRules for cryptography and key management
MITRE CAPECCAPEC-97 Cryptanalysis, CAPEC-620 Drop Encryption LevelAttack patterns behind the OWASP brute-force and downgrade scenarios

Common pitfalls

  • Obfuscating instead of protecting: splitting a key across strings or XOR-ing it with a constant only delays extraction; dynamic instrumentation reads it at the moment of use. Obfuscation belongs to M7, not M10.
  • Reusing a GCM nonce: a fixed or counter-reset nonce under one key breaks both confidentiality and integrity. Let the library generate it, or use a random 96-bit nonce per message.
  • Trusting a "fast" password hash: deriving a local encryption key from a four-digit PIN with one SHA-256 pass is brute-forced offline in seconds. Use a Keystore or Secure Enclave key gated by device authentication, or a server-side rate-limited check, rather than relying on KDF cost alone.
  • Silent fallback: catching StrongBoxUnavailableException or a Keystore error and falling back to a software key in SharedPreferences, or to an older algorithm, is the downgrade OWASP lists as an attack scenario. Fall back only to another hardware-backed option.
  • Ignoring the verification result: signature checks wrapped in try/catch that continue on exception, or comparing MACs with a non-constant-time equals, pass every test that only checks the happy path.
  • Forgetting the backup path: keys or tokens in non-ThisDeviceOnly Keychain classes, or files outside no-backup directories, can follow the user to another device or a backup archive. See the GoTo Breach 2023 for what happens when encrypted backups and their key are taken together.

Practitioner checklist

  • Build a crypto inventory for each app from the release binary, with algorithm, mode, key source and purpose per call site.
  • Remove every key and secret from the binary and rotate any that ever shipped.
  • Generate app keys in Android Keystore or the Secure Enclave, with fixed purposes, and check the reported security level.
  • Use AES-256-GCM or ChaCha20-Poly1305 with unique nonces, SHA-256 or better, HMAC-SHA256 and ECDSA P-256 or Ed25519.
  • Use SecureRandom or the platform key generators for every key, IV and token.
  • Bind high-value keys to user authentication and an unlocked device; use ThisDeviceOnly Keychain classes.
  • Version every ciphertext with a key ID and test the rotation and migration path.
  • Fail release builds on ECB, MD5, SHA-1, insecure RNG and hard-coded key material, after a report-only period.
  • Test MASVS-CRYPTO-1 and -2 with static and dynamic analysis each major release and keep the evidence.
  • Track hardware-backed key ratio and weak-algorithm call sites as release metrics.

Standards and references

Related NHI Mgmt Group resources: OWASP Mobile Top 10 Guide · Mobile App Security Guide · Encryption Guide · Crypto-Agility Guide · OWASP Mobile Top 10 M9 Insecure Data Storage Guide

PDF for subscribers

Take this guide with you

Every section, table and checklist in one PDF, with links to the sources and related guides. Subscribe to our weekly NHI & AI Identity Journal and we’ll email you a download link.

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Researched and written by the NHI Mgmt Group editorial team using AI tools, under the editorial direction of Lalit Choda. Facts are drawn from the sources listed on this page and checked by our automated quality process. Last updated 26 October 2026. Spotted an error? Use our contact page.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM and Agentic AI security. nhimg.org

PDF Downloads for Newsletter Subscribers

Get the guide

Enter your details and we’ll email you a download link.

The full guide is free to read online. The PDF is a thank you for subscribing.

Fill in all fields marked * and tick the PDF box to continue.