Task classifier (intent → path)
| User intent | Path |
|---|---|
| Key comes from AndroidKeyStore / hardware-backed key | → Keystore audit(Step 1) |
| Locate crypto call sites / intercept ciphertext and plaintext | → crypto hook(Step 2) |
| Analyze third-party crypto libraries (BoringSSL / OpenSSL / Tink / libsodium, etc.) | → Library analysis(Step 3) |
When to use / when not to use
- Use: Android app crypto audit—key system (Keystore), encryption/decryption call chain, library selection recovery
- Use:
getEncoded()unavailable hardware-backed key (must go through audit rather than extracting key bytes) - Use: during crypto interception, key alias and purpose need to be recorded (do not record key bytes—security boundary)
- Do not use: JNI/so native logic reverse engineering (use [[re-android-native]]); generic crypto algorithm identification (use [[re-crypto-id]]); generic key extraction ([[re-crypto-keys]], except Keystore hardware keys)
- Do not use: non-Android platforms (use the generic crypto domain [[re-protocol]] branch)
- Boundary: this skill covers the full spectrum of Android crypto audit—Keystore/Cipher/KeyInfo/hook as the starting point, and analysis of third-party libraries such as BoringSSL/OpenSSL/Tink/libsodium is included in this skill (Step 3), not stuffed into re-android-native
Tool preparation
Verify all tools before use. Dynamic hooking defaults to sandbox ([[re-analyze/platform-tips]] highest principle); static auditing may skip the sandbox.
frida ([[re-frida]])—the mainstay of crypto hooking
- Installation and verification see [[re-frida]] Tool preparation; script templates see [[re-frida/frida-scripts]]
- Verification:
frida --version
python3 / jadx—statically locate crypto call sites
- python3 installation and verification see [[re-python]] Tool preparation
- jadx installation and verification see [[re-apk]] Tool preparation
Device-side commands ([[re-apk]] adb section)
adb shellObtain app runtime state (KeyStore enumeration must be executed within the app process)
Procedure
-
Keystore audit(AndroidKeyStore key system):
// 应用进程内枚举(frida 注入或 jadx 反编译定位调用点) KeyStore ks = KeyStore.getInstance("AndroidKeyStore"); ks.load(null); java.util.Enumeration<String> aliases = ks.aliases();- Iterate over:
aliases()enumerate all entries (key alias = in-app reference key) - Entry attributes: algorithm (AES/RSA/EC), purpose (encrypt/decrypt/sign/verify), origin—
KeyInfo.getSecurityLevel()(API 31+, returns three tiers SOFTWARE / TRUSTED_ENVIRONMENT(TEE) / STRONGBOX); API 23–30 only hasisInsideSecureHardware()(boolean, TEE and StrongBox are both true, cannot be distinguished) - Biometric binding:
setUserAuthenticationRequiredkeys are unavailable when authentication fails (bypass and detection see [[re-analyze/anti-dynamic-workflow]]) - Output: alias → algorithm/purpose/hardware backing list (do not record key bytes)
- Iterate over:
-
crypto hook(crypto call-site interception):
// frida:拦截加密调用点,记录算法/模式/密钥别名 // 别名来源:Key 对象本身不携带别名(KeyStore 无 getKeyAlias),须在 getKey 处记录 const KeyStore = Java.use('java.security.KeyStore'); KeyStore.getKey.overload('java.lang.String', '[C').implementation = function (alias, password) { console.log('KeyStore.getKey', alias); return this.getKey(alias, password); }; const Cipher = Java.use('javax.crypto.Cipher'); Cipher.init.overload('int', 'java.security.Key', 'java.security.spec.AlgorithmParameterSpec').implementation = function (opmode, key, params) { console.log('Cipher.init', opmode, key.getClass().getName(), params); // 对应别名见上方 getKey 输出 return this.init(opmode, key, params); }; // 另路取回别名:SecretKeyFactory.getInstance(key.getAlgorithm(), 'AndroidKeyStore') // .getKeySpec(key, KeyInfo.class) → KeyInfo.getKeystoreAlias()- hook target:
Cipher.initseries (algorithm/mode/IV source),KeyStore.getKey/getEntry(alias and purpose),Signature/Macinitialization (signature verification/verification chain) - Record: alias and purpose,do not record key bytes(security boundary, see Pitfall 2)
- Static location aid: jadx search
AndroidKeyStore/KeyStore.getInstance/Cipher.getInstancecall sites, cross-verify with hook results
- hook target:
-
Third-party crypto library analysis(BoringSSL / OpenSSL / Tink / libsodium, etc.):
- Identify: import table/symbols (
SSL_*/EVP_*/crypto_*/sodium_*prefix) + jadx dependency declarations - Locate call sites: xrefs of library APIs (static) or hook library-exported functions (dynamic)
- Connect with [[re-android-native]]: libraries exist as .so → their JNI/internal logic goes through [[re-android-native]], this skill handles crypto semantics (algorithm/key source/purpose)
- Identify: import table/symbols (
-
Outputs and evidence preservation: key system diagram (alias/algorithm/purpose/endorsement source) + crypto call site list + hook scripts, sha256 archived for [[re-ioc]] reference
Cross-domain combination
- [[re-android-native]]: JNI/so native logic reverse engineering (the receiver for the internal logic of .so libraries in this skill; Keystore auditing is transferred out of it)
- [[re-frida]]: hook execution layer ([[re-frida/frida-scripts]] templates)
- [[re-crypto-id]] / [[re-crypto-keys]]: algorithm identification and general key extraction (except Keystore hardware keys — those go through this skill's auditing)
- [[re-apk]]: application static location (jadx call sites)
- [[re-mobile]]: workflow mobile branch (crypto audit subpath)
Common pitfalls and traps
- Treating Keystore as an ordinary key extraction: symptom —
getEncoded()cannot obtain key bytes, mistakenly concludes "the key does not exist"; cause — AndroidKeyStore hardware-backed keys are non-exportable, this is by design rather than a deficiency; countermeasure — switch to auditing (step 1: alias/algorithm/purpose/endorsement), do not pursue key bytes - Confusing TEE and StrongBox: symptom —
isInsideSecureHardwarebeing true is taken to assert StrongBox; cause — Secure Hardware includes two levels, TEE and StrongBox, and this interface is boolean and cannot distinguish them (isStrongBoxBackedonKeyGenParameterSpec, only covers the generation side,KeyInfodoes not); countermeasure — on API 31+ useKeyInfo.getSecurityLevel()to get the three tiers SOFTWARE / TEE / STRONGBOX; API 23–30 cannot subdivide, so label the conclusion as "secure hardware (TEE or StrongBox)" tier - Recording key bytes: symptom — hook scripts print/write Keystore key contents to disk; cause — treating auditing as extraction, crossing the security boundary; countermeasure — only record alias and purpose, key bytes are not written to disk (see step 2 note)
- Treating library semantics as JNI logic analysis: symptom — third-party crypto libraries' .so files are deeply mined as native logic while crypto semantics are ignored; cause — unclear domain; countermeasure — the crypto semantics of library APIs (algorithm/key source/purpose) belong to this skill, only internal implementation details go through [[re-android-native]]