How Android backup hashes are extracted
Inside the adb backup text header: how PBKDF2 salts, round counts, and a master-key blob become a crackable $ab$ hash.
When a user runs adb backup with a password, Android serialises the device data into a .ab file in which the tar payload is AES-256-encrypted. The encryption parameters needed to attack that password live in a short, human-readable text header at the very start of the file — everything else is ciphertext. Hash Extractor reads that header in the browser, assembles a $ab$ hash, and hands it to hashcat or John the Ripper without the backup ever leaving your machine.
The .ab file layout
An Android backup file is not a binary container from the first byte. It starts with a sequence of newline-delimited text lines, then the encrypted tar payload begins immediately after. The text header has exactly nine lines in this order:
- The literal string
ANDROID BACKUP— the magic that identifies the format. - A version number (1 through 5 in practice).
- A compression flag (
0or1). - The encryption algorithm —
AES-256for an encrypted backup,nonefor an unencrypted one. - The user-password PBKDF2 salt, hex-encoded.
- The master-key checksum salt, hex-encoded.
- The PBKDF2 round count (an integer, typically
10000). - The user-key IV, hex-encoded.
- The master-key blob, hex-encoded.
Every binary value is transmitted as a lowercase hex string, so the header is entirely ASCII. The extractor reads at most the first 4096 bytes and processes only these nine lines; it never touches the encrypted payload.
Detection and validation
Detection is a single prefix check on the raw bytes:
ANDROID BACKUP
If the first 14 bytes do not match that string, the file is rejected immediately. After confirming the magic, the parser reads the encryption algorithm line. A value of none returns NotEncrypted — there is nothing to crack. Any algorithm other than AES-256 returns Unsupported. Only a file that passes both checks proceeds to hash assembly.
Key derivation model
Android uses PBKDF2-HMAC-SHA1 to derive a 256-bit user key from the backup password and the user salt. That user key is then used to AES-decrypt the master-key blob. The blob contains the actual AES master key used to encrypt the tar payload, a copy of that master key's IV, and a HMAC that allows verification. The checksum salt feeds a second PBKDF2 derivation used to verify the master key after unwrapping.
A password cracker does not need to decrypt the payload at all. It re-derives the user key for each candidate password, decrypts the master-key blob, and checks the embedded HMAC against the checksum salt. A match means the password is correct. All the material needed for that loop — both salts, the round count, the IV, and the blob — is in the text header.
The $ab$ hash format
The extractor assembles the hash as:
$ab$<version>*0*<rounds>*<user_salt>*<ck_salt>*<user_iv>*<master_key_blob>
The 0 in the second field is a fixed flag (reserved for future use in the format specification). All hex strings are lowercased before insertion. The field order matches what hashcat mode 18900 and John's AndroidBackup format expect.
A concrete example
The extractor's test suite exercises a version-5 backup with these header values:
| Header line | Value |
|---|---|
| Version | 5 |
| Compression | 1 |
| Algorithm | AES-256 |
| User salt | aaaaaaaaaaaaaaaa (8 bytes, hex) |
| Checksum salt | bbbbbbbbbbbbbbbb (8 bytes, hex) |
| PBKDF2 rounds | 10000 |
| User IV | cccccccccccccccccccccccccccccccc (16 bytes, hex) |
| Master-key blob | dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd (52 bytes, hex) |
The assembled hash is:
$ab$5*0*10000*aaaaaaaaaaaaaaaa*bbbbbbbbbbbbbbbb*cccccccccccccccccccccccccccccccc*dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
This mirrors the output of androidbackup2john exactly — the extractor was written to produce the same token layout.
Cracking with hashcat and John the Ripper
hashcat
echo '$ab$5*0*10000*aaaaaaaaaaaaaaaa*bbbbbbbbbbbbbbbb*cccccccccccccccccccccccccccccccc*dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd' > hash.txt
hashcat -m 18900 hash.txt /usr/share/wordlists/rockyou.txt
Mode 18900 is Android Backup. hashcat handles the PBKDF2 derivation, AES unwrap, and HMAC verification on GPU.
John the Ripper
john --format=AndroidBackup hash.txt --wordlist=/usr/share/wordlists/rockyou.txt
Both tools accept the same $ab$ token — no conversion is needed between them.
Why client-side extraction matters
The .ab file can contain SMS history, app data, contacts, and credentials. Uploading it to a remote service to extract the hash would expose that data to a third party before you have even started cracking. Hash Extractor runs the Rust parser compiled to WebAssembly entirely in the browser. The file is read locally, the hash is assembled in memory, and only the short $ab$ string — containing no user data, only cryptographic parameters — is shown on screen. The backup payload is never transmitted anywhere.
This is the same principle behind the classic androidbackup2john script, which likewise extracts only the header fields. The WASM implementation brings the same workflow to any browser without requiring a Python or Perl runtime.