Extracting Hardcoded Symmetric Keys from Binaries via Static Reverse Engineering
Theory
Why This Matters
Hardcoded cryptographic keys are among the most frequently exploited vulnerability classes in embedded systems and mobile applications. CVE-2012-2122 (MariaDB/MySQL authentication bypass) involved a hardcoded comparison, and the Philips Hue firmware (2020 research) contained hardcoded symmetric keys used to protect device provisioning traffic — extracted from the firmware binary in under ten minutes using strings and entropy analysis. The US CISA advisory AA22-137A (2022) identified hardcoded credentials as a top exploited weakness across industrial control system (ICS) firmware. In Android APK reverse engineering, hardcoded AES keys embedded in Java classes or native libraries are routinely recovered using jadx decompilation, enabling decryption of locally cached user data and server communications. Understanding key extraction from binaries is a foundational skill for firmware security assessments, mobile application security reviews, and CTF challenges in the reversing/crypto intersection.
Core Concept
A hardcoded key is a cryptographic key value embedded directly in source code, compiled binary, bytecode, or configuration file rather than being loaded from a secure key store at runtime. From a cryptographic standpoint, hardcoded keys violate the principle of key separation: the key material is accessible to anyone with access to the artefact, making the key effectively public for all users of that software version.
The attack surface spans multiple artefact types:
Source code: Keys appear as string or byte literals (e.g., key = b"0123456789abcdef"), hexadecimal constants, or Base64-encoded strings. Version control history may retain keys even after they are removed from HEAD.
Compiled binaries (ELF/PE): AES-128 keys are 16 consecutive non-zero bytes; AES-256 keys are 32 bytes. They are often recognisable by entropy analysis: high-entropy regions in a binary's .data or .rodata section correlate with key storage. strings extracts printable sequences ≥4 characters. binwalk -E plots entropy across the binary; key arrays appear as sharp high-entropy blocks.
Android APKs: APKs are ZIP archives. jadx decompiles .dex bytecode to Java source, where hardcoded byte arrays, string keys, and SecretKeySpec(new byte[]{...}) calls are plainly visible. Native libraries (.so files) inside the APK require strings or Ghidra/IDA analysis.
Configuration files and environment variables: Keys stored in .env, config.yaml, application.properties, or similar files. truffleHog and gitleaks scan repositories for high-entropy strings matching key patterns.
The detection heuristic for AES keys is: a contiguous byte sequence of exactly 16, 24, or 32 bytes that is non-null, non-repeating, and has Shannon entropy > 3.5 bits/byte. Base64-encoded AES-256 keys are 44 characters; hex-encoded AES-128 keys are 32 hex characters — both detectable by regex.
Technical Deep-Dive
# Step 1: Extract printable strings from binary
strings -n 8 firmware.bin | grep -E '[A-Za-z0-9+/]{22,}={0,2}$' # Base64
strings -n 8 firmware.bin | grep -E '[0-9a-fA-F]{32,64}' # Hex key
# Step 2: Entropy analysis with binwalk
binwalk -E firmware.bin # plot entropy; key regions appear as spikes to ~1.0
binwalk -e firmware.bin # extract embedded filesystems
# Step 3: Android APK analysis
unzip app.apk -d apk_extracted/
jadx -d jadx_out/ apk_extracted/classes.dex
# Search decompiled source for key patterns
grep -r "SecretKeySpec|AESKey|getBytes|KEYs*=" jadx_out/ | head -30
grep -rP '(?:[0-9a-fA-F]{2}s*,s*){15,31}[0-9a-fA-F]{2}' jadx_out/ # byte arrays
# Step 4: Secrets scanning on git repositories
trufflehog git file://. --only-verified
gitleaks detect --source . --report-path findings.json
# Step 5: Use recovered key to decrypt (Python example for AES-CBC)
from Crypto.Cipher import AES
# Key recovered from binary (example pattern — not a real key)
recovered_key = bytes.fromhex("REPLACE_WITH_RECOVERED_HEX_KEY")
# IV often immediately precedes or follows the key in memory
recovered_iv = bytes.fromhex("REPLACE_WITH_RECOVERED_IV")
def decrypt_with_recovered_key(ciphertext: bytes, key: bytes, iv: bytes) -> bytes:
cipher = AES.new(key, AES.MODE_CBC, iv)
pt = cipher.decrypt(ciphertext)
# Strip PKCS#7 padding
pad = pt[-1]
if 1 <= pad <= 16 and pt[-pad:] == bytes([pad]*pad):
pt = pt[:-pad]
return pt
Cryptanalysis Methodology
- Obtain the artefact — Download the firmware from the vendor website, pull the APK from an Android device (
adb pull /data/app/...), or clone the repository. For compiled binaries, confirm the architecture (file firmware.bin). - Run
stringsand grep for key patterns — Extract all printable strings ≥8 characters. Filter for: Base64 strings of length 24 (AES-128) or 44 (AES-256), hex strings of length 32 or 64, and strings matching common key variable names (KEY, SECRET, AES, CIPHER). - Perform entropy analysis with binwalk — Run
binwalk -Eand identify high-entropy regions. Note their file offsets. Extract bytes at those offsets and test as candidate keys. - Decompile bytecode — For Android APKs, use
jadx. For .NET assemblies, usednSpyorILSpy. Search forSecretKeySpec,Cipher.getInstance,KeyGenerator, and hardcoded byte array initialisers. - Search version control history — Use
truffleHogorgit log -S "key_pattern"to find keys that were present in earlier commits but removed. Hardcoded keys removed from code may still be in production on deployed systems. - Confirm the key by decrypting a known ciphertext — If the application has a known-plaintext (e.g., a predictable response format, a magic header), attempt decryption with each candidate key. A correct decryption produces recognisable plaintext.
- Assess impact and report — Document the algorithm (AES-128-CBC, AES-256-GCM, etc.), the key and IV values as found, what data they protect, and the full attack chain from key extraction to data decryption.
Secure Implementation Note — Never hardcode cryptographic keys in source code or compiled artefacts. Use a secrets management solution: HashiCorp Vault, AWS Secrets Manager, Azure Key Vault, or GCP Secret Manager for server-side applications; Android Keystore or iOS Secure Enclave for mobile apps. Environment variables are an improvement over hardcoding but must themselves be protected by access controls and never committed to version control. Use SOPS or sealed secrets for encrypted secrets-at-rest in configuration files.
Common Cryptanalysis Errors
- Extracting only printable strings and missing binary key arrays — AES keys stored as raw byte arrays (not hex or Base64 encoded) will not appear in
stringsoutput. Usebinwalk -Eentropy analysis and examine.rodata/.datasection bytes directly with a hex editor. - Confusing IV with key — In firmware, AES keys and IVs are often stored adjacently. Swapping them (using the IV as the key) produces garbage decryption. Test both orderings if the first attempt fails.
- Testing only AES-128 (16 bytes) when the key is AES-256 (32 bytes) — Many firmware images use AES-256. If 16-byte candidates fail, search for 32-byte high-entropy sequences.
- Not checking git history — A key removed in the most recent commit may still be present in hundreds of previous commits and thus in every deployed binary built before the removal. Always scan git history with truffleHog.
- Ignoring obfuscation layers — Some developers XOR-encode the hardcoded key with a fixed constant before storing it. If decryption with a raw candidate key fails, look for adjacent small constants that might be XOR masks.
- Stopping after finding one key — Complex applications may use multiple hardcoded keys for different data categories (e.g., one for local storage, one for API communication). Enumerate all candidates before concluding the assessment.
NICE Framework Alignment
| Code | Knowledge/Skill/Task Statement | How This Card Develops It |
|---|---|---|
| K0018 | Knowledge of encryption algorithms | Identifies how hardcoded keys undermine the security of otherwise sound symmetric ciphers |
| K0019 | Knowledge of cryptography and cryptographic key management concepts | Motivates proper key management infrastructure as the essential complement to cipher selection |
| K0305 | Knowledge of data concealment | Demonstrates that encryption with a recoverable key provides no real confidentiality |
| S0138 | Skill in using public-key encryption and PKI | Develops binary and bytecode analysis skills for key extraction applicable across firmware, mobile, and desktop targets |
| T0259 | Conduct vulnerability assessment using established frameworks | Trains systematic hardcoded-key discovery as a component of firmware and mobile application security assessments |
Further Reading
- Extracting Keys from Hardware Security Modules — Colin O'Flynn, DEF CON 27 Hardware Hacking Village, 2019
- Android Application Security (Chapter 5: Cryptography) — Ken Dunham and Tim Wyatt, Syngress, 2014
- NIST SP 800-57 Part 1 Rev. 5: Recommendation for Key Management — NIST, 2020
Challenge Lab
Reinforce your learning with a hands-on generated challenge based on this card's competency.