The Android Keystore system exists for one purpose: to keep cryptographic keys away from attackers. But weak key configurations, broken cipher choices, and flawed key derivation routinely undermine it. This post covers the most common cryptographic vulnerabilities in Android apps and how to identify and exploit them during a security assessment.
The Android Keystore — What It Actually Protects
The Android Keystore stores keys in hardware-backed secure storage (TEE or StrongBox) when available. Keys generated inside the Keystore never leave it in plaintext — cryptographic operations happen inside the secure enclave. The problem is almost never the Keystore itself. It is the configuration of keys stored in it, and the cryptographic operations performed with them.
Finding Keystore Misconfigurations
The most critical misconfigurations are: keys with no user authentication requirement, keys with overly broad purposes, and keys with insufficient key size. All are auditable at runtime with Frida.
A key with userAuthRequired=false is accessible to any process running as the app — including a compromised process or a malicious library loaded into the app. On rooted devices this means the key can be used to sign arbitrary data or decrypt sensitive content without any user awareness.
Broken Cipher Implementations
Even when the Keystore is used correctly, the cipher operation wrapping it can be fatally flawed. The classic failures are ECB mode (leaks data patterns, deterministic), static IVs (makes AES-CBC equivalent to ECB), and weak key derivation (passwords hashed with MD5, no salt).
Runtime Crypto Interception with Frida
When source code is unavailable, hook the Java crypto primitives directly. The Cipher.doFinal() method is the universal intercept point — every AES/RSA/DES operation passes through it.
Hardcoded Keys and Secrets
A large proportion of Android crypto vulnerabilities come from hardcoded keys — baked into the APK in BuildConfig, string resources, or native libraries. Static analysis finds most of them in minutes.
# Scan decompiled APK for crypto material
grep -rn "SecretKeySpec\|AES\|HMAC\|hardcoded\|password\|secret" output/ --include="*.java" -i
grep -rn "[A-Za-z0-9+/](32,)=(0, 2)" output/ --include="*.java" # Base64 blobs
strings lib/arm64-v8a/libnative.so | grep -E "[A-F0-9](32,)" # Hex keys in .so
Remediation Priorities
- Always use AES-GCM (authenticated encryption) — never ECB, never static IV with CBC
- Set
setUserAuthenticationRequired(true)on all Keystore keys that protect sensitive operations - Use
setUserAuthenticationValidityDurationSeconds(-1)to require biometric per-operation - Derive keys from passwords using PBKDF2WithHmacSHA256 with >= 100,000 iterations and a random 128-bit salt
- Never store raw keys in SharedPreferences, files, or SQLite — use the Keystore for all key material
- Enable StrongBox where available (
setIsStrongBoxBacked(true)) for highest-value keys
Cryptographic vulnerabilities in Android apps are some of the most impactful bugs in mobile security — they often lead directly to credential theft, session hijacking, or complete data compromise. For hands-on labs covering Android crypto exploitation, Mobile Hacking Lab includes dedicated cryptography challenges in the CAED certification track.



