Signal Desktop LevelDB and SQLCipher Forensic Analysis: Recovering Encrypted Messages

Signal Desktop stores messages in an SQLCipher-encrypted SQLite database at db.sqlite. The encryption key sits in a config file protected by OS-level primitives (Windows DPAPI or macOS Keychain). For forensic investigators with local access to the workstation the messages are recoverable through documented methodology. Sherlock Forensics walks through the storage layout, the LevelDB cache role, the key extraction path and the recovery workflow suitable for court-defensible reporting.

Why Signal Desktop forensics matters: Signal has become the dominant end-to-end encrypted messenger for security-conscious individuals and organizations. The desktop client persists the entire message history to disk in an SQLCipher database. For investigators handling workstation evidence (corporate laptop, home desktop, seized device) the on-disk Signal Desktop store is the primary source for recovering conversation content. The recovery is deterministic when the operator has the local key and reasonable when the key is available through DPAPI or Keychain unprotection.

Where Signal Desktop Stores Its Data

Signal Desktop is an Electron application. Its user data lives in an OS-conventional application data directory that Electron manages. On Windows the path is %APPDATA%\Signal\ which resolves to C:\Users\USERNAME\AppData\Roaming\Signal\. On macOS the path is ~/Library/Application Support/Signal/. On Linux the path is ~/.config/Signal/. The directory contains the encrypted SQLite database, a LevelDB cache directory, an attachments directory and a configuration file that holds the database encryption key in wrapped form.

The critical files for forensic recovery are config.json (holds the DPAPI-wrapped or Keychain-wrapped database encryption key), sql/db.sqlite (the SQLCipher-encrypted message database), attachments.noindex/ (raw attachment binaries indexed by hash) and Local Storage/leveldb/ (Chromium-standard LevelDB storing session state, contact metadata and application preferences). Each of these plays a role in the recovery workflow.

The SQLCipher Encrypted Database

Signal Desktop uses SQLCipher which is a fork of SQLite that transparently encrypts the database at rest with AES-256 in CBC mode with HMAC-SHA512 authentication. The encryption key is a 256-bit random value stored in the config.json file in wrapped form. When Signal Desktop starts it unwraps the key via the OS primitive (DPAPI unprotect on Windows or Keychain retrieval on macOS or an equivalent secret-store on Linux) and passes it to SQLCipher to unlock the database. All queries against the message store go through the SQLCipher pragma-key mechanism which handles the encryption transparently.

For forensic recovery the database file db.sqlite is unreadable with standard SQLite tools without the key. Attempting to open it produces a "file is not a database" error because the header bytes are ciphertext not the standard SQLite magic. Recovery requires the key extraction path documented below.

The Key Extraction Path on Windows

On Windows the Signal Desktop database key is wrapped via DPAPI (Data Protection API) with the current user's login credentials as the entropy source. The wrapped key sits in config.json in a base64-encoded blob under the encryptedKey field. To unwrap the key an investigator needs to run DPAPI CryptUnprotectData under the target user's security context. This is available in two scenarios: live-response on the running workstation with the user logged in (or with admin credentials to impersonate) or offline recovery with the user's password (which allows DPAPI master key derivation via the standard DPAPI-NG algorithms).

The live-response path is straightforward: run a small utility (Signal_Decrypt.exe pattern or a custom PowerShell script using System.Security.Cryptography.ProtectedData) under the target user context to unwrap the key. The offline path is more involved and uses the DPAPI master key stored in %APPDATA%\Microsoft\Protect\SID\ combined with the SHA1 of the user's password. Public tools like impacket's dpapi.py and mimikatz's dpapi module implement the offline path. Investigators handling a seized workstation without live access typically use the offline path with a known password or a cracked password from the SAM hive.

Once the key is unwrapped it is passed to SQLCipher via pragma key = 'x''<64-hex-key>''' before any query. Any SQLCipher-aware tool (sqlcipher CLI, DB Browser for SQLite with SQLCipher build, custom Python with pysqlcipher3) opens the database at that point. The recovered database contains the standard Signal message schema described below.

The Key Extraction Path on macOS

On macOS the wrapped key is stored in the login Keychain (not in config.json). Signal Desktop retrieves it via the Security framework SecKeychainFindGenericPassword call at startup. For forensic recovery an investigator needs Keychain access which requires either the user's login password (which decrypts the login Keychain) or a live-response session with the Keychain unlocked. The macOS security CLI tool retrieves the item with security find-generic-password -s "Signal Safe Storage" -w after unlock.

The offline path on macOS is similar to Windows offline DPAPI: with the user password the login Keychain file at ~/Library/Keychains/login.keychain-db is decryptable using documented Keychain format tools. Public projects like ChainBreaker and keychaindump implement the offline extraction. Once the key is retrieved the SQLCipher unlock proceeds identically to the Windows path.

The Signal Message Schema Investigators Query

The Signal Desktop schema is documented in the open-source Signal-Desktop repository on GitHub. The primary tables for investigator queries are messages (holds every message the client has sent or received), conversations (holds one-to-one and group conversation metadata), sessions (holds Signal Protocol session state) and preKeys (holds one-time key material). Investigators focus on the messages table.

The messages table columns include id (UUID identifier), json (the full message payload in JSON form including body, timestamp, sender identifier, attachment references), sent_at (message send timestamp in Unix milliseconds), received_at (device-receive timestamp), conversationId (foreign key to conversations), type (message type discriminator such as incoming, outgoing, verified-change, keychange), source (sender phone number for incoming), sourceUuid (sender Signal UUID). The json column holds the authoritative message body and metadata; other columns are indexed extractions from it.

For attribution the conversations table maps conversationId to a human-readable identifier (phone number for one-to-one, group name and member list for group chats). The join across messages and conversations produces a per-conversation flat listing suitable for investigator review.

The LevelDB Cache Role

The Local Storage/leveldb/ directory holds Chromium's LevelDB storage engine content. Electron applications inherit Chromium's storage layer and Signal Desktop uses it for session state, view preferences, some contact metadata caches and Electron internal state. The LevelDB store is not encrypted and is directly parseable with any LevelDB reader (Python plyvel, Go leveldb, ldb CLI from the LevelDB reference implementation).

For forensic recovery the LevelDB content typically supplements the SQLCipher recovery. It may contain session identifiers, last-active timestamps and configuration state that helps establish timeline and device fingerprint. In some Signal Desktop versions particular metadata leaks into LevelDB that is not present in db.sqlite; investigators should extract and review the LevelDB store separately for completeness.

The LevelDB directory structure follows the standard LevelDB SSTable and MANIFEST layout: numbered .ldb files hold the sorted-string-table records, a CURRENT file references the active manifest and MANIFEST-NNNNNN files describe the log structure. Any LevelDB reader walks the structure and dumps key-value pairs. Investigators typically dump to text and grep for identifiers relevant to the investigation.

Attachment Recovery from the Local Store

Signal Desktop attachments (images, videos, documents) are stored in the attachments.noindex/ directory indexed by content-addressable hash. The messages json payload references attachments by hash and by MIME type. To recover a specific attachment an investigator queries the messages table for the target message, extracts the attachment hash from the json payload and looks up the file in attachments.noindex/ by hash prefix (the directory is sharded by leading two hex characters).

Attachments themselves are stored encrypted at rest with a per-attachment key derived from the master database key. The Sherlock recovery methodology handles the derivation automatically: given the master key from the SQLCipher unlock the per-attachment key falls out via the documented key-derivation scheme and the ciphertext-to-plaintext decryption proceeds without further operator input.

Chain of Custody and Court Defensibility

Forensic recovery of Signal Desktop data must be documented rigorously to support court submission. The Sherlock chain-of-custody documentation records the source workstation identifier, the acquisition timestamp, the file hashes of config.json and db.sqlite and any LevelDB files before and after acquisition, the DPAPI or Keychain unlock method used, the examiner identity and the tool version. The recovered messages are exported with per-message hashes and a manifest describing the recovery methodology.

Opposing counsel in Signal-related evidence disputes routinely challenges the chain of custody and the recovery methodology. The documentation package produced during recovery is the load-bearing defense against those challenges. Investigators should preserve the original db.sqlite ciphertext file alongside the decrypted export so a validation-run can be replayed if requested.

Prior Security Research That Informs the Methodology

Multiple security researchers have documented Signal Desktop's key storage and recovery methodology across 2020 to 2025. Notable work: Nathan Suchy's 2018 analysis of Signal Desktop key storage that flagged the lack of a passphrase on the wrapped key; the 2022 Bleeping Computer coverage of Signal Desktop database extraction; Talos's 2023 analysis of Signal Desktop on macOS Keychain integration; and multiple GitHub proof-of-concept repositories demonstrating the DPAPI unwrap path on Windows. Signal's own maintainers have acknowledged the design trade-off: a passphrase-protected local key would improve at-rest security but degrade the user experience for the majority of users who do not face targeted local-access threats.

For forensic investigators the takeaway is that Signal Desktop recovery is a documented and reproducible methodology, not a novel exploit. Investigators can proceed with confidence that the methodology withstands defensive scrutiny in court because it relies on documented OS primitives and open-source Signal client behavior.

What This Means for Investigators in 2026

Signal Desktop message recovery is a routine capability that investigators handling workstation evidence should have in their toolkit. The recovery yield is high when local key material is accessible (live-response or offline with user password). The methodology is court-defensible when documented rigorously. The Sherlock tool catalog includes DFIR tools that cover the workstation acquisition path (Sherlock Disk Imager for the raw acquisition and Sherlock Browser Viewer for adjacent browser artifacts that corroborate the Signal timeline). Combined with the documented Signal Desktop recovery methodology those tools support end-to-end workstation forensics in-house.

For engagements requiring dedicated encrypted messaging recovery capacity Sherlock Forensics offers the incident response service model with the recovery expertise built in. For organizations preferring internal capacity the workstation acquisition tools plus the documented Signal Desktop recovery methodology produce reproducible results in-house. Either model supports the modern investigative reality that encrypted messaging content is often the highest-value evidence in fraud, IP-theft and misconduct cases.