Deconstructing Encrypted Communication Protocol Artifacts (Signal/WhatsApp)
End-to-end encryption (E2EE) protects message content in transit, but mobile devices still maintain local state to function. On a physical or full file-system acquisition, you can frequently recover accounts, device identifiers, contact and group identifiers, message timing, call history, media references, and even local key material or key handles. Your goal in DFIR is to turn these device-resident artifacts into defensible timelines of who communicated with whom, when, and how often.
- Signal and WhatsApp both implement the Signal Protocol (Double Ratchet) for E2EE; each message derives fresh keys for forward secrecy and post-compromise security, so decrypting one message does not unlock others (Signal Double Ratchet spec).
- Signal’s service is deliberately metadata-minimal; historically, server logs retained only registration time and last-connect time, not contact lists or conversation graphs (Signal transparency responses, follow-up 2021). Client features like Sealed Sender further hide who is messaging whom at the service layer (Signal blog: Sealed Sender; typing indicators are sent via the same protected channel when enabled, limiting server visibility (Signal support: Typing Indicators)).
- WhatsApp adopts the Signal Protocol for E2EE and stores message history in on-device databases; it also produces encrypted local backups on Android (crypt14/crypt15) that require a device-resident key or user key to decrypt (Tom’s Hardware report on adoption).
Why this matters: even when content remains unreadable, you can extract identities (JIDs, UUIDs, phone numbers), conversation thread membership, message timestamps, call logs, device links, and event frequency-enough to reconstruct communication patterns.
Technical Background
- Android protects app secrets using the Android Keystore/KeyMint stack, which can bind keys to hardware and make key material non-exportable (Android Keystore overview, AOSP KeyMint/Keystore architecture). Apps typically store databases under
/data/data/<package>/with access restricted to the app UID; recovering these paths generally requires physical, root, or full file-system extractions. - iOS protects secrets with Keychain and can bind operations to the Secure Enclave; Keychain itself is a SQLite store with access enforced by entitlements (Apple platform security: Keychain, Protecting keys with Secure Enclave). Full file-system extraction (e.g., checkm8-based workflows on supported devices/versions) is usually necessary to access protected app data for E2EE messengers (Belkasoft on iOS Signal extraction).
- Signal stores its local message database encrypted with SQLCipher across platforms. On desktop, artifacts include
db.sqliteplus an encryption key referenced viaconfig.json(newer builds store an encrypted key that tools can resolve), enabling examiners with lawful access to decrypt for verification (DC3 advisory path summary, tc3.dev walkthrough). On Android and iOS phones the Signal DB remains SQLCipher-encrypted and its keying is managed via the platform keystore/keychain (DC3 advisory). - New as of October 2025: Signal Secure Backups provide optional, end-to-end encrypted chat backups (including all texts and 45 days of media for free; expanded paid media storage), gated by a 64-character recovery key that Signal never sees (Signal support: Secure Backups, Signal blog announcement). This is distinct from the long-standing Signal PIN secure-value-recovery used for profile/contacts metadata, not content (Signal blog: SVR, PIN FAQ).
Step-by-Step Guide
You’ll work per app and per OS. Always confirm you have legal authority, and prefer full physical/file-system extractions to preserve context and timestamps.
A. WhatsApp (Android)
- Confirm installation and acquire
- Package:
com.whatsapp. Full file-system/physical extractions are preferred to access/data/data/com.whatsapp/and external storage. Scoped storage moves user-visible Databases underAndroid/media/com.whatsapp/WhatsApp/Databaseson Android 11+ (Android Police/Yahoo syndication guide).
- Artifact locations
- Main working DBs (SQLite) under app sandbox:
/data/data/com.whatsapp/databases/msgstore.db(messages/chats) and/data/data/com.whatsapp/databases/wa.db(contacts) (Magnet artifact profile, CIRT/Group-IB write-up).
- Encrypted backups (external/scoped storage):
.../WhatsApp/Databases/msgstore.db.crypt14(and dated variants) (Android Police/Yahoo).
- Backup decryption key (Android device, rooted or via full FS extraction):
/data/data/com.whatsapp/files/key(fileinfo.com format page, WhatsApp Chat Exporter README).
- Additional DBs of interest:
companion_devices.db(linked devices) (CyberDB summary).
- What they reveal
wa.db→ WhatsApp JIDs, phone numbers, display names, and timestamps (look forwa_contacts) (CIRT/Group-IB).msgstore.db→ thread list and messages; key tables commonly includechat_listandmessageswith timestamps, message direction/status, attachment references, and sometimes location fields (Magnet).- External backups (
.crypt14/.crypt15) can be decrypted with the device key or user’s crypt15 recovery key to obtain a SQLitemsgstore.dbfor analysis (wa-crypt-tools, WhatsApp Chat Exporter).
- Practical extraction
- If you have full FS access: copy
/data/data/com.whatsapp/databases/and/data/data/com.whatsapp/files/key. - If only external storage is available: copy
Android/media/com.whatsapp/WhatsApp/Databases/*.crypt14and, if lawfully obtained, thekeyfrom the device to decrypt with tooling (wa-crypt-tools).
- Quick SQL for frequency and timing (after you obtain a readable
msgstore.db)
-- Top counterparties by message count
SELECT m.key_remote_jid AS jid, COUNT(*) AS msg_count
FROM messages m
GROUP BY m.key_remote_jid
ORDER BY msg_count DESC
LIMIT 20;
-- Daily activity volume
SELECT date(m.timestamp/1000, 'unixepoch') AS day, COUNT(*) AS msgs
FROM messages m
GROUP BY day
ORDER BY day;
(Table names align to common schemas reported in practitioner research; verify on your version before use) (Magnet).
B. WhatsApp (iOS)
- Confirm installation and acquire
- Bundle:
net.whatsapp.WhatsApp. Prefer full file-system or at least an iTunes-style backup with keychain (when permitted). Core DBs reside in the WhatsApp App Group container.
- Artifact locations and meaning
ChatStorage.sqlite(messages), typically under the App Group container (e.g.,/private/var/mobile/Containers/Shared/AppGroup/group.net.whatsapp.WhatsApp.shared/), with key tables likeZWAMESSAGEandZWAMEDIAITEMfor messages/media; identifiers show JIDs such as@s.whatsapp.net(contacts) and@g.us(groups) (Sudo Null/Group-IB mirror, Belkasoft iOS guide).CallHistory.sqlite(VoIP calls) andContactsV2.sqlite(contacts) in the same group area are valuable for timelines and roster corroboration (Belkasoft).
- Quick SQL (iOS)
-- By chat (ZWACHATSESSION links sessions to messages)
SELECT s.ZCONTACTJID AS jid,
COUNT(m.Z_PK) AS msgs,
MIN(m.ZMESSAGEDATE) AS first_ts,
MAX(m.ZMESSAGEDATE) AS last_ts
FROM ZWAMESSAGE m
JOIN ZWACHATSESSION s ON m.ZCHATSESSION = s.Z_PK
GROUP BY s.ZCONTACTJID
ORDER BY msgs DESC;
(Schema per observed versions; validate on extraction) (Belkasoft).
C. Signal (Android)
- Confirm installation and acquire
- Package:
org.thoughtcrime.securesms. You will need a full file-system/physical extraction to access the app sandbox and the Android Keystore handle that protects the SQLCipher key.
- Artifact locations
- Encrypted DB:
/data/data/org.thoughtcrime.securesms/databases/signal.db(SQLCipher) (DC3 advisory). - Preferences and identifiers:
/data/data/org.thoughtcrime.securesms/shared_prefs/org.thoughtcrime.securesms_preferences.xml(may include registered number and flags) (DC3 advisory). - Attachments:
/data/data/org.thoughtcrime.securesms/app_parts/(encrypted at rest) (DC3 advisory). - The database key is protected by the Android Keystore (non-exportable by design), often under a keystore alias similar to
USRSKEY_SignalSecretmapped to the app UID; acquisition approaches depend on device state and OS version (DC3 advisory mapping, Android Keystore overview).
- What you can learn
- Even without plaintext content, the DB maintains thread, recipient, and message metadata that enable frequency/timing analysis. Signal’s Android codebase shows Room/SQLite models for messages, recipients, and threads (names vary by version), and the store is SQLCipher-encrypted on disk (Signal Android repo, community documentation aggregations such as ReadmeX indicating SQLCipher and Room usage for
SignalDatabaseand message/recipient tables-validate against your specific version) (ReadmeX summary).
- New backups to consider (2025)
- If the device owner enabled Signal Secure Backups, a cloud backup may exist that is end-to-end encrypted and recoverable only with the 64-character recovery key; daily refresh excludes view-once and imminent disappearing messages (Signal support, Signal blog). This is distinct from legacy, device-local Android
.backupfiles that required a passphrase and a user-selected folder (Signal Android backup docs-historical).
D. Signal (iOS)
- Confirm installation and acquire
- Bundle:
org.whispersystems.signal/Signal(current bundle isorg.whispersystems.signalunder Signal’s App Group). You typically need a full file-system extraction plus Keychain to decrypt Signal’s SQLCipher store.
- Artifact locations
- Encrypted DB:
/var/mobile/Containers/Shared/AppGroup/<UUID>/grdb/signal.sqlite(SQLCipher) (DC3 advisory). - Attachments:
/var/mobile/Containers/Shared/AppGroup/<UUID>/Attachments(DC3 advisory). - Keychain item:
GRDBDatabaseCipherKeySpecforGRDBKeyChainServiceholds the database cipher key material (protected by the Secure Enclave/data protection class); tools that can lawfully extract/decrypt the Keychain can open the DB (DC3 advisory, Apple Keychain details). - Apple backups (iTunes/iCloud) historically do not include Signal chat history; use full FS extraction or the new Secure Backups feature if present (Signal support FAQ, Belkasoft on iOS Signal).
- What you can learn
- As on Android, threads/recipients/messages exist in the local DB and support timing/frequency reconstruction once decrypted. Remember that disappearing/view-once behavior affects what persists locally and in Secure Backups (Signal support: Secure Backups).
Key Artifacts and Evidence
Below are high-value locations and what they tell you. Validate exact paths/schemas for the specific version you’re examining.
-
WhatsApp Android:
/data/data/com.whatsapp/databases/wa.db→ full WhatsApp contact roster with display names, numbers, JIDs, and timestamps (CIRT/Group-IB)./data/data/com.whatsapp/databases/msgstore.db→ messages, statuses, attachments, call events; combine withwa.dbto attribute identities (Magnet)./data/data/com.whatsapp/files/key→ device backup key for crypt12/14 decryption (fileinfo.com, WhatsApp Chat Exporter).Android/media/com.whatsapp/WhatsApp/Databases/*.crypt14→ encrypted message store backups (Android Police/Yahoo).companion_devices.db→ linked device info (establishes desktop/web usage) (CyberDB).
-
WhatsApp iOS:
- App Group container (e.g.,
group.net.whatsapp.WhatsApp.shared) →ChatStorage.sqlite(ZWAMESSAGE/ZWAMEDIAITEM),ContactsV2.sqlite,CallHistory.sqlite(messages, contacts, calls) (Belkasoft, SudoNull/Group-IB).
- App Group container (e.g.,
-
Signal Android:
/data/data/org.thoughtcrime.securesms/databases/signal.db(SQLCipher), prefs XML, attachments directory; DB key protected via Android Keystore (non-exportable by design) (DC3, Android Keystore).
-
Signal iOS:
- App Group →
grdb/signal.sqlite(SQLCipher),Attachmentsfolder; Keychain itemGRDBDatabaseCipherKeySpecused to unlock DB (DC3, Apple Keychain).
- App Group →
-
OS corroboration (usage timelines):
- Android UsageStats APIs/DBs capture app usage intervals and last time used, supporting app-presence timelines (Android UsageStatsManager).
- iOS KnowledgeC/Biome databases record app usage and many device events; KnowledgeC path:
/private/var/mobile/Library/CoreDuet/Knowledge/knowledgeC.db(full FS needed), with modern versions increasingly using Biome streams (MSAB note, Belkasoft guide).
Identification Techniques
- Locate the application containers quickly
- Search for package/bundle identifiers (
com.whatsapp,org.thoughtcrime.securesms,net.whatsapp.WhatsApp) in your file system view to jump to app sandboxes and App Group containers (Magnet overview of locations, DC3 artifact list).
- Decode WhatsApp identities
- WhatsApp JIDs end with
@s.whatsapp.net(contacts) or@g.us(groups); use this to separate person-to-person vs group activity (Belkasoft iOS WhatsApp).
- Correlate Signal threads without content
- Query thread/recipient tables (after lawful decryption) to count messages per recipient and chart inter-message intervals. Signal’s codebase reflects message/recipient/thread modeling in Room/SQLite; table names evolve, so inspect the schema first (Signal Android repo, ReadmeX overview).
- Cross-validate with OS telemetry
- Align chat DB timestamps with KnowledgeC/Biome (iOS) or usage stats (Android) to show app foreground use near message bursts (MSAB, Android UsageStats).
Practical Examples
Example 1: WhatsApp-“who talked to whom, when, how often” (Android)
-- Join contacts to messages by JID
WITH msgs AS (
SELECT key_remote_jid AS jid,
timestamp/1000 AS ts,
CASE WHEN key_from_me=1 THEN 'out' ELSE 'in' END AS dir
FROM messages
)
SELECT w.display_name,
m.jid,
COUNT(*) AS total_msgs,
SUM(CASE WHEN dir='out' THEN 1 ELSE 0 END) AS sent,
SUM(CASE WHEN dir='in' THEN 1 ELSE 0 END) AS received,
MIN(datetime(ts,'unixepoch')) AS first_msg,
MAX(datetime(ts,'unixepoch')) AS last_msg
FROM msgs m
LEFT JOIN wa_contacts w ON w.jid = m.jid
GROUP BY m.jid, w.display_name
ORDER BY total_msgs DESC;
(Works on common wa.db/msgstore.db layouts; verify table/column names per version) (Magnet artifact profile, CIRT/Group-IB).
Example 2: WhatsApp-call timeline (iOS)
-- Call history summary
SELECT datetime(ZDATE/1000,'unixepoch') AS when,
ZCALLTYPE, ZDURATION,
ZADDRESS
FROM ZCALLRECORD
ORDER BY ZDATE;
(Exact tables/fields may vary; iOS stores call records in CallHistory.sqlite in the App Group) (Belkasoft iOS WhatsApp).
Example 3: Signal-thread frequency (general approach)
- After lawful decryption (Android via keystore-assisted tooling; iOS via Keychain), list tables and identify thread/recipient mapping, then count by thread. Names often include variants of
messages,recipients,threadsper app version (Signal Android repo, ReadmeX summary).
-- Pseudocode-like SQL: adapt to discovered schema
SELECT r.address AS recipient,
COUNT(m._id) AS msgs,
MIN(m.date_sent) AS first_ts,
MAX(m.date_sent) AS last_ts
FROM messages m
JOIN recipients r ON r._id = m.recipient_id
GROUP BY r.address
ORDER BY msgs DESC;
Validation and Pitfalls
- Relying on cloud backups alone. Signal’s content was historically absent from iOS/Android cloud backups; as of Oct 2025, Secure Backups are opt-in and require the recovery key to access-without it, no decryption is possible (Signal backup FAQ).
- Assuming schema stability. Both apps evolve schemas; always dump the actual schema from the device before running queries (e.g., WhatsApp message tables and Signal Room entities change over time) (Magnet note on evolving artifacts).
- Missing scoped-storage paths on modern Android. WhatsApp’s local backup location under
Android/media/com.whatsapp/WhatsApp/Databasesis easy to overlook if you expect legacy/sdcard/WhatsApp/Databases/(Android Police/Yahoo). - SQLCipher settings. When validating Signal desktop DBs, you must use SQLCipher 4 defaults and a raw key (or decrypt the newer
encryptedKey)-omit this and tools will report “invalid database” (tc3.dev how-to). - Key material misconceptions. WhatsApp’s external backups need the device key; Signal’s mobile DB keys are keystore/keychain-protected and generally non-exportable by design (fileinfo.com crypt14, Android Keystore, Apple Keychain).
Best Practices
- Acquire as completely as possible. Prefer full physical/file-system extractions to capture app sandboxes, App Group containers, and keychain/keystore blobs (Belkasoft iOS Signal).
- Corroborate across layers. Align app DB timestamps with OS usage (KnowledgeC/Biome on iOS, UsageStats on Android) to strengthen “who/when/how often” conclusions (MSAB, Android UsageStatsManager).
- Extract identities carefully. On WhatsApp, normalize JIDs and map to phone numbers and display names from
wa.db; on Signal, use recipient/thread tables (post-decryption) and device-registered phone/username features as applicable (CIRT/Group-IB, Signal blog on usernames/number privacy). - Document encryption states. For each artifact, note whether it was encrypted at rest (SQLCipher, crypt14) and how you lawfully obtained decryption (device key, keychain item, user-supplied recovery key) (wa-crypt-tools, Signal Secure Backups).
- Validate tool output. Cross-check vendor tool parsing with manual SQLite/SQLCipher inspection to avoid silent field mapping errors (Magnet guidance on custom artifacts).
Takeaways
- E2EE prevents network/content interception, but device-resident artifacts still reveal communication structure.
- On WhatsApp,
wa.dbandmsgstore.db(Android) andChatStorage.sqlite(iOS) are the primary sources for contacts, threads, and message timing; external backups (.crypt14/.crypt15) hinge on the device key or user’s recovery key. - On Signal, both Android and iOS store SQLCipher-encrypted databases with keys protected by the platform keystore/keychain; new Secure Backups (Oct 2025) introduce opt-in, end-to-end encrypted cloud archives recoverable only with a 64-character recovery key.
- Cross-validate app artifacts with OS telemetry (KnowledgeC/Biome, UsageStats) to defend “who/when/how often” conclusions without message content.
With careful acquisition, schema validation, and correlation, you can reliably answer the core DFIR questions about E2EE messengers: who communicated, when, how frequently, and across which devices, while respecting the cryptographic boundaries that protect content.
Sources / References
- Signal Double Ratchet Specification: https://signal.org/docs/specifications/doubleratchet/
- Signal blog: Sealed Sender: https://signal.org/blog/sealed-sender/
- Signal support: Typing Indicators: https://support.signal.org/hc/en-us/articles/360020798451-Typing-Indicators
- Signal transparency (2016 subpoena): https://signal.org/bigbrother/eastern-virginia-grand-jury/
- Signal transparency (2021 subpoena): https://signal.org/bigbrother/central-california-grand-jury/
- Tom’s Hardware: WhatsApp adopts Signal protocol: https://www.tomshardware.com/news/whatsapp-signal-complete-end-to-end-encryption%2C31555.html
- Android Developers: Keystore overview: https://developer.android.com/privacy-and-security/keystore
- AOSP: Hardware-backed Keystore / KeyMint: https://source.android.com/docs/security/features/keystore
- Apple Platform Security: Keychain: https://support.apple.com/en-euro/guide/security/secb0694df1a/web
- Apple Developer: Protecting keys with the Secure Enclave: https://developer.apple.com/documentation/security/protecting-keys-with-the-secure-enclave
- DC3 Technical Advisory (Signal artifacts summary): https://content.govdelivery.com/accounts/USDODDC3/bulletins/2e03518
- tc3.dev: Extracting Messages from Signal Desktop: https://www.tc3.dev/posts/extracting-messages-from-signal-desktop/
- Signal support: Secure Backups (2025): https://support.signal.org/hc/en-us/articles/9708267671322-Signal-Secure-Backup
- Signal blog: Introducing Secure Backups: https://signal.org/blog/introducing-secure-backups/
- Signal blog: Secure Value Recovery: https://signal.org/blog/secure-value-recovery/
- Signal support: PIN / SVR info: https://support.signal.org/hc/en-us/articles/360007059792-PIN-di-Signal
- Magnet Forensics: WhatsApp Artifact Profile: https://www.magnetforensics.com/blog/artifact-profile-whatsapp-messenger/
- CIRT/Group‑IB: WhatsApp forensic artifacts: https://www.cirt.gov.bd/whatsapp-in-plain-sight-forensic-artifacts-group-ib/
- Android Police/Yahoo: Find WhatsApp backups (scoped storage path): https://tech.yahoo.com/phones/articles/whatsapp-message-backups-google-drive-233110583.html
- fileinfo.com: CRYPT14 file format and key path: https://fileinfo.com/extension/crypt14
- WhatsApp Chat Exporter (supports crypt12/14/15; key path): https://github.com/KnugiHK/WhatsApp-Chat-Exporter
- wa‑crypt‑tools (decrypt crypt12/14/15): https://pypi.org/project/wa-crypt-tools/
- CyberDB: Android WhatsApp forensics (companion_devices.db): https://www.cyberdb.co/getting-to-grips-with-android-whatsapp-forensics/
- Belkasoft: iOS WhatsApp forensics (ChatStorage/ContactsV2/CallHistory): https://belkasoft.com/ios-whatsapp-forensics-with-belkasoft-x
- Sudo Null/Group‑IB: WhatsApp iOS artifact locations: https://sudonull.com/post/30099-WhatsApp-in-the-palm-of-your-hand-where-and-how-can-you-detect-forensic-artifacts-Group-IB-Blog
- Belkasoft: Decrypting iOS Signal (why full FS): https://belkasoft.com/decrypting_ios_signal
- Signal Android repo (schema evolves; SQL/Room, SQLCipher at rest): https://github.com/signalapp/Signal-Android
- ReadmeX: Signal Android database/Room & SQLCipher overview: https://readmex.com/en-US/signalapp/Signal-Android/page-3e2f0c455-e5b5-4650-b98c-29bfc33809c4
- MSAB: KnowledgeC and Biome forensic locations: https://www.msab.com/blog/hidden-gems-in-apple-ios-digital-forensics/
- Belkasoft: How to analyze KnowledgeC.db: https://belkasoft.com/how-to-analyze-knowledgec-database-with-belkasoft-x
- Android Developers: UsageStatsManager: https://developer.android.com/reference/android/app/usage/UsageStatsManager
- Magnet Forensics: Dynamic App Finder / custom artifacts: https://www.magnetforensics.com/blog/using-dynamic-app-finder-to-recover-more-mobile-artifacts/
- Signal blog: Phone-number privacy and usernames: https://signal.org/blog/phone-number-privacy-usernames/