01Location
- /data/data/org.thoughtcrime.securesms/databases/signal.db
02Questions it answers
- Is Signal installed, and does an encrypted message store exist on the device?
- If lawfully decrypted by an appropriate process, which conversations and recipients are present?
- Were messages set to disappear or be viewed once, or deleted remotely?
03Format and versions
| Format | SQLCipher-encrypted SQLite (net.zetetic SQLCipher library). The database secret is 32 random bytes; on current builds it is sealed with an AES-GCM key (alias SignalSecret) held in the Android Keystore and stored only in sealed form. Tables include message (date_sent, date_received, date_server, type, thread_id, from_recipient_id, to_recipient_id, body, read, expires_in, expire_started, view_once, deleted_by), thread, recipient and attachment (message_id, content_type, data_file, file_name). |
|---|---|
| Applies to | Described from the current open-source Signal-Android code; older installs may still hold a legacy unencrypted secret that the code reads before the sealed one. Table and column names change across releases. |
04Key fields
| Field | What it tells you |
|---|---|
| message.date_sent / date_received / date_server | Sender time, local receipt time and server time. |
| message.thread_id → thread | Conversation the message belongs to. |
| message.from_recipient_id / to_recipient_id → recipient | Sender and recipient references. |
| message.expires_in / expire_started | Disappearing-message timer and when it started. |
| message.view_once / deleted_by | View-once flag and remote-deletion marker. |
| attachment.data_file / content_type | Local file reference and MIME type of an attachment. |
05Timestamps
| Field | Encoding | Note |
|---|---|---|
| message.date_received | Unix epoch, milliseconds | Set from System.currentTimeMillis() on receipt. |
| message.expires_in | Milliseconds (duration) | Derived from the recipient's timer in seconds converted to milliseconds. |
Decode raw values with the Timestamp decoder and convert local wall-clock times with the Local time to UTC.
06Examination workflow
- Document the presence, size and timestamps of signal.db and related files without altering them.
- Record the app version, since schema and key handling depend on it.
- Analyse content only through a lawful, validated process; then map message → thread → recipient.
- Treat expiry fields as configuration; missing messages may have expired.
07Interpretation pitfalls
- Without the database secret, signal.db content is not readable; this record does not cover key recovery.
- Disappearing messages are removed by the app after expiry, so their absence is expected behaviour.
- Schema details come from the current source tree; verify them for the installed version.
09Sources
- Signal-Android — SignalDatabase.kt Signal (signalapp/Signal-Android on GitHub) · checked 2026-10-14
- Signal-Android — DatabaseSecretProvider.java Signal (signalapp/Signal-Android on GitHub) · checked 2026-10-14
- Signal-Android — KeyStoreHelper.java Signal (signalapp/Signal-Android on GitHub) · checked 2026-10-14
- Signal-Android — MessageTable.kt Signal (signalapp/Signal-Android on GitHub) · checked 2026-10-14
- Signal-Android — AttachmentTable.kt Signal (signalapp/Signal-Android on GitHub) · checked 2026-10-14
- Signal-Android — app/build.gradle.kts (namespace) Signal (signalapp/Signal-Android on GitHub) · checked 2026-10-14