Messaging and appsAdvancedMessaging

Signal for Android database (signal.db)

Signal Android signal.db: SQLCipher-encrypted store with message, thread, recipient and attachment tables; key sealed via Android Keystore.

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

FormatSQLCipher-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 toDescribed 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

FieldWhat it tells you
message.date_sent / date_received / date_serverSender time, local receipt time and server time.
message.thread_id → threadConversation the message belongs to.
message.from_recipient_id / to_recipient_id → recipientSender and recipient references.
message.expires_in / expire_startedDisappearing-message timer and when it started.
message.view_once / deleted_byView-once flag and remote-deletion marker.
attachment.data_file / content_typeLocal file reference and MIME type of an attachment.

05Timestamps

FieldEncodingNote
message.date_receivedUnix epoch, millisecondsSet from System.currentTimeMillis() on receipt.
message.expires_inMilliseconds (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

  1. Document the presence, size and timestamps of signal.db and related files without altering them.
  2. Record the app version, since schema and key handling depend on it.
  3. Analyse content only through a lawful, validated process; then map message → thread → recipient.
  4. 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

  1. Signal-Android — SignalDatabase.kt Signal (signalapp/Signal-Android on GitHub) · checked 2026-10-14
  2. Signal-Android — DatabaseSecretProvider.java Signal (signalapp/Signal-Android on GitHub) · checked 2026-10-14
  3. Signal-Android — KeyStoreHelper.java Signal (signalapp/Signal-Android on GitHub) · checked 2026-10-14
  4. Signal-Android — MessageTable.kt Signal (signalapp/Signal-Android on GitHub) · checked 2026-10-14
  5. Signal-Android — AttachmentTable.kt Signal (signalapp/Signal-Android on GitHub) · checked 2026-10-14
  6. Signal-Android — app/build.gradle.kts (namespace) Signal (signalapp/Signal-Android on GitHub) · checked 2026-10-14