Android System Securing, Hardening, & Privacy

Frida & Ghidra for Keystore Bypass: Live Tampering with Android’s Hardware Security Module

Google AdSense Native Placement - Horizontal Top-Post banner

Introduction: Unpacking Android’s Hardware-Backed Keystore

The Android Keystore System provides a robust mechanism for storing cryptographic keys in a secure container, protecting them from compromise. For critical applications, developers can specify that keys be “hardware-backed,” meaning they are stored and used within a Trusted Execution Environment (TEE) or a dedicated Hardware Security Module (HSM) like StrongBox. This design significantly raises the bar for attackers, as keys never leave the secure hardware, making extraction exceedingly difficult. However, understanding how applications interact with these hardware-backed keys at runtime can reveal potential bypasses by tampering with the application’s perception or use of these keys, rather than directly extracting them from the TEE.

This article delves into advanced techniques using static analysis with Ghidra and dynamic instrumentation with Frida to identify and potentially subvert the use of hardware-backed keys within an Android application. Our focus is not on breaking the TEE itself, but on manipulating the application’s logic that relies on these secure keys, effectively bypassing their protective measures from the application’s perspective.

Prerequisites for the Journey

To follow along with these techniques, you’ll need the following:

  • A rooted Android device (physical or emulator) with Magisk or similar for Frida-server.
  • ADB (Android Debug Bridge) installed and configured.
  • Ghidra: The open-source reverse engineering framework.
  • Frida: The dynamic instrumentation toolkit.
  • A target Android application (APK) that utilizes hardware-backed keystore keys. For demonstration, consider a simple application that encrypts user data with a hardware-backed key.
  • Basic understanding of Android application structure, Java/Kotlin, and native C/C++ development (JNI).

Understanding Android Keystore and its Hardware Roots

The Android Keystore system, exposed through the KeyChain API, allows apps to store cryptographic keys. When creating keys, developers can specify various security characteristics, including:

  • setUserAuthenticationRequired(): Requires user authentication (PIN, fingerprint) for key use.
  • setIsStrongBoxBacked(): Requests a key to be stored in a StrongBox-backed KeyStore.
  • setUnlockedDeviceRequired(): Requires the device to be unlocked.

Hardware-backed keys, particularly those in StrongBox, offer superior protection because cryptographic operations (encryption, decryption, signing) are performed entirely within the secure hardware. The raw key material is never exposed to the Android OS kernel, making traditional memory dumping or kernel-level attacks ineffective for key extraction. Our attack vector instead targets the application’s interface with these secure operations.

Phase 1: Static Analysis with Ghidra – Mapping the Attack Surface

The first step is to understand how the target application interacts with the Android Keystore. This involves disassembling the APK using Ghidra to identify relevant code paths.

Step-by-Step Ghidra Workflow:

  1. Load the APK into Ghidra: Open Ghidra, create a new project, and import the target APK. Ghidra will prompt you to analyze it.
  2. Initial Java Analysis: Start by analyzing the Java bytecode. Search for key Keystore-related classes and methods:
    • android.security.keystore.KeyGenParameterSpec
    • java.security.KeyStore.getInstance("AndroidKeyStore")
    • javax.crypto.KeyGenerator or java.security.KeyPairGenerator
    • javax.crypto.Cipher, java.security.Signature, javax.crypto.Mac
  3. Identify Key Generation/Import: Focus on methods that generate or import keys. Look for constructors of KeyGenParameterSpec and calls to init() methods of KeyGenerator or KeyPairGenerator, particularly those setting `setIsStrongBoxBacked(true)` or related flags.
  4. Trace Key Usage: Once a key is identified, trace its usage. Look for calls to KeyStore.load(), KeyStore.getEntry(), and then subsequent use of the key with Cipher.init(), Signature.initSign(), or Signature.initVerify().
  5. JNI Investigation: Many complex applications offload cryptographic operations to native libraries (JNI) for performance or security through obfuscation. If you find calls to native methods (e.g., `System.loadLibrary(“mylib”)`, `native_function_name`), switch your analysis to the corresponding native library (e.g., `libmylib.so`).
  6. Native Code Analysis in Ghidra: In the native library, search for references to `AndroidKeyStore` or functions that might wrap JNI calls to the Keystore API. Look for symbols like `JNI_OnLoad` to understand how the library initializes and registers its native methods. Trace function calls from the Java native methods to the underlying C/C++ code.

Ghidra Search Example (Java):

Search > For Strings >

Android Mobile Specs & Compare Directory

Are you researching mobile hardware properties, processor SoCs, GPU chipsets, or RAM configurations? Access our complete specs catalog to compare up to 5 devices side-by-side!

Compare Devices Specs →
Google AdSense Inline Placement - Content Footer banner