SuperAPI AI Directory

re-android-crypto

Security & auditing

View repository

Updated 10-15 21:34

About this skill

Android crypto audit

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 shell Obtain app runtime state (KeyStore enumeration must be executed within the app process)

Procedure

  1. 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 has isInsideSecureHardware()(boolean, TEE and StrongBox are both true, cannot be distinguished)
    • Biometric binding:setUserAuthenticationRequired keys 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)
  2. 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.init series (algorithm/mode/IV source),KeyStore.getKey / getEntry(alias and purpose),Signature/Mac initialization (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.getInstance call sites, cross-verify with hook results
  3. 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)
  4. 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 —isInsideSecureHardware being true is taken to assert StrongBox; cause — Secure Hardware includes two levels, TEE and StrongBox, and this interface is boolean and cannot distinguish them (isStrongBoxBacked on KeyGenParameterSpec , only covers the generation side,KeyInfo does not); countermeasure — on API 31+ use KeyInfo.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]]