May 18, 2026 · 6 min read

Crypt15 explained

Crypt15 is the format every Android WhatsApp backup uses since 2021. AES-256-GCM, 32-byte root key, an HMAC-SHA256-based key derivation matching wa-crypt-tools, gzip-compressed SQLite. The precise pipeline, and why Chat Hoarding can decrypt locally without a server.

crypt15whatsapp encryptiontechnical

Crypt15 is what landed when WhatsApp turned on E2E-encrypted backups in October 2021. The spec is well-understood by the open-source community. The only thing it requires of the user is the 64-digit key WhatsApp shows you once.

The Crypt15 wire format

A Crypt15 file is a protobuf-prefixed AES-256-GCM ciphertext. The header is a protobuf message describing the IV (12 or 16 bytes), the format version, and the encryption variant. The body is the encrypted payload. When decrypted, it's a gzipped SQLite database: msgstore.db, the WhatsApp message store. (wa.db, the contacts database, is not part of the user-accessible Crypt15 backup; it lives inside WhatsApp's private app directory and needs root to read.)

Key derivation

Your 64-digit hex key is a 32-byte root key. Chat Hoarding app parses it (LicenseState aside, this is the only key that matters) and runs it through an HMAC-SHA256-based key derivation: the same `encryptionLoop` construction wa-crypt-tools uses, with the info string 'backup encryption', to produce the AES-256-GCM key. (It's not standard HKDF; it's a fixed-iteration HMAC loop that WhatsApp's Android client implements.) The IV comes from the protobuf header (12 or 16 bytes). AES-GCM authenticates the ciphertext, so a wrong key fails with an authentication tag mismatch rather than garbage output, and bad keys are caught instantly.

Decompression

After AES-GCM the payload is gzipped SQLite. Chat Hoarding pipes it through Foundation's gunzip and writes msgstore.db to the staging folder of the .tarc bundle. msgstore.db is the only database that ends up in the user-accessible Crypt15 backup; contacts come from the phone's address book, not from a separate decrypted DB.

What's inside msgstore.db

  • message: one row per message, with status, sender JID, timestamp, body, key_id
  • message_media: image/video/audio/document metadata, file paths, captions
  • message_quoted: reply context for quoted messages
  • chat: per-conversation summary, mute state, archived flag, last message id
  • jid: phone-number / @lid mapping table
  • group_participant_user: group membership over time
  • receipt_user: per-recipient delivered/read/played timestamps
  • message_revoked: sender-deleted messages (still present, marked)

Why Crypt15 enables an archiver at all

The format is well-documented in the open-source community (wa-crypt-tools and friends). What Chat Hoarding app adds on top is a native Mac client, an archive format, the rendering layer, and licensing: the parts that make the spec usable rather than the spec itself.

FAQ

Can Chat Hoarding decrypt Crypt12 or Crypt14?

No. Today only Crypt15 is supported. Crypt12 and Crypt14 are legacy formats from before E2E backups; if you only have one of those, restore on the phone and run a fresh backup to upgrade to Crypt15 first.

What if I lose my 64-digit key?

The backup is unrecoverable. WhatsApp's E2E design means the key never touches WhatsApp's servers. Always copy the key somewhere safe (1Password, a printed sheet in a safe) before any phone migration.

What about iCloud / iPhone backups?

iPhone WhatsApp uses Apple's protected backup, not Crypt15. iPhone support is on the roadmap and will use the iTunes/Finder backup path with libimobiledevice, a different pipeline entirely.

Related reading

Stop reading. Start archiving.

$99 lifetime · 2 Macs · revocable

Crypt15 explained · Chat Hoarding