Articles

Investigating Session Desktop: Decryption and Artefact Analysis on Windows and macOS
Close-up of hands typing on a laptop displaying cybersecurity graphics, illuminated by purple light.


Analysing Session chat application on Windows and macOS

Author: Arun KALACKATTU HARI (06/03/2026)

Session is an open-source, public-key-based secure messaging application designed to provide private and anonymous communication. The platform uses the Session encryption protocol together with the Oxen blockchain’s decentralised Service Node network to transmit messages without relying on centralised infrastructure.

Instead of routing communications through traditional servers, Session messages are relayed across distributed Service Nodes organised within the Oxen network. Messages are transmitted using onion routing, meaning that each message passes through multiple nodes before reaching its destination. This architecture prevents any single node from identifying both the sender and the recipient, significantly reducing metadata exposure.

Unlike many messaging platforms that require phone numbers or email addresses, Session generates a cryptographic account identity locally on the user’s device. This identity is derived from a public/private key pair and allows users to communicate without linking their real-world identity to the application.

This article examines how Session Desktop stores its artefacts on Windows and macOS systems, how its encryption mechanisms operate, and the methodology required to decrypt and reconstruct conversations and attachments during forensic analysis.

Location of Session Data
Windows

On Windows systems, Session stores its application data within the user’s roaming profile:

C:\Users\<username>\AppData\Roaming\Session\

Each Windows user account maintains its own independent Session directory. When analysing forensic images, this directory is typically accessible once the relevant user profile has been mounted.

macOS

On macOS systems, Session user artefacts are stored at:

/Users/<username>/Library/Application Support/Session/

Session Artefacts

The primary artefacts within the Session directory include:

config.json
Contains configuration settings and cryptographic material required by the application.

db.sqlite
An SQLCipher-encrypted SQLite database storing conversations, messages, metadata, and internal encryption material.

attachments.noindex/
A directory containing encrypted attachment blobs.

These artefacts must be analysed together in order to reconstruct conversations and recover associated media attachments.

Session Configuration File (config.json)

The config.json file contains configuration parameters used by the Session client as well as cryptographic material associated with database access.

Example configuration:

{
  "key": "d406a9688fc33ee2b8f93bc8d83f1a4dc4347aba1b6a07c96f2c2bb548108813",
  "opengroupPruning": true,
  "dbHasPassword": false
}

Two operational scenarios may be encountered during forensic analysis depending on the value of the dbHasPassword parameter.

Scenario 1 – No Application Password Enabled
{
  "key": "d406a9688fc33ee2b8f93bc8d83f1a4dc4347aba1b6a07c96f2c2bb548108813",
  "opengroupPruning": true,
  "dbHasPassword": false
}

When dbHasPassword is false, the SQLCipher key stored in the key field can be used directly to decrypt the db.sqlite database.

In this configuration:

  • The database encryption key is stored in config.json
  • The database can be opened using this key together with the required SQLCipher parameters
  • No additional user password is required
Scenario 2 – Application Password Enabled
{
  "key": "d406a9688fc33ee2b8f93bc8d83f1a4dc4347aba1b6a07c96f2c2bb548108813",
  "opengroupPruning": true,
  "dbHasPassword": true
}

When dbHasPassword is true, the user has enabled an application unlock password within the Session client.

In this configuration:

  • The application password replaces the key stored in config.json as the credential used to unlock the SQLCipher-encrypted database.
  • The key stored in config.json alone is not sufficient to decrypt db.sqlite.
  • The user-defined application password must be supplied to access the database.

Database Encryption (SQLCipher)

db.sqlite is encrypted using SQLCipher, which implements AES-256 encryption.

Key characteristics include:

  • The encryption key is stored in config.json
  • The key is represented as a 64-character hexadecimal value
  • The database cannot be opened without the correct key and cipher configuration

SQLCipher parameters used during forensic analysis include:

PRAGMA cipher_default_compatibility = 4;
PRAGMA cipher_page_size = 4096;
PRAGMA kdf_iter = 256000;
PRAGMA cipher_hmac_algorithm = HMAC_SHA512;
PRAGMA cipher_kdf_algorithm = PBKDF2_HMAC_SHA512;

Once the correct key and parameters are applied, the encrypted database can be queried to perform analysis.

JSON-Centric Data Storage

Session stores much of its internal application data within JSON structures embedded inside SQLite tables.

These JSON objects may contain:

  • Message bodies
  • Sender identifiers
  • Attachment metadata
  • Original filenames
  • Message timestamps

This structure differs from traditional relational schemas and requires additional parsing when reconstructing conversations.

Attachment Encryption

Media attachments are protected using a separate encryption mechanism.

Session encrypts attachments using ‘libsodium’s secretstream API’, specifically the XChaCha20-Poly1305 authenticated encryption scheme.

Key characteristics include:

  • Each attachment is encrypted individually
  • Attachments use a separate encryption key from the database
  • The attachment encryption key is stored inside db.sqlite.
  • Attachments cannot be decrypted until the database has been successfully decrypted
Extracting the Attachment Encryption Key

Within the decrypted database, the attachment encryption key is stored inside the items table under the entry:

'local_attachment_encrypted_key'

This value is stored as JSON data.

Attachment Decryption Process

Analysis of the TypeScript(ts) code responsible for attachment encryption (available in the Session GitHub repository) clearly documents how media attachments are encrypted and provides a reliable reference for forensic decryption.

Session uses:

  • XChaCha20 for encryption
  • Poly1305 for authentication and tamper detection

Each attachment file follows a consistent structure:

For each attachment:

  1. Initialise a libsodium secretstream pull state
  2. Decrypt the encrypted payload
  3. Identify the file type using magic byte signatures
  4. Write the decrypted file with the appropriate extension

This process converts encrypted attachment blobs into usable media files.

Restoring Original Filenames

Session stores original filenames within message metadata contained inside JSON objects in the database.

Using this metadata, decrypted attachments can be renamed to their original filenames.

During this process:

  • Filenames are sanitised for filesystem compatibility
  • File extensions are preserved
  • Naming collisions are handled safely

This step transforms previously unreadable encrypted blobs into recognisable files suitable for review and disclosure.

Forensic Analysis of the iOS Signal Application
joa70 data security 9145391

Forensic Analysis of the iOS Signal Application

Author: Arun KALACKATTU HARI (26/02/2026)


Signal is widely regarded as one of the most secure messaging applications available today.
Its architecture prioritises privacy through strong end-to-end encryption, modern
cryptographic standards, and secure local storage.
This article outlines the forensic analysis of Signal on iOS, the methodology used to decrypt
its encrypted database, and the development of a custom parser to extract messages, calls,
and attachments in a structured manner.
This article outlines:

  • The location of Signal artefacts on iOS
  • Decryption of the SQLCipher-protected database
  • Interpretation of message, call, and attachment structures
  • Attachment decryption methodology
  • Development of a custom Python GUI parser to automate structured extraction

Location of Signal Data on iOS
On iOS devices, Signal stores its user data within the shared App Group container:
/private/var/mobile/Containers/Shared/AppGroup//
The folder structure within this signal directory is :

screenshot 2026 03 02 at 9.40.58 am

the primary user database is located at:
/grdb/Signal.sqlite
This database contains message content, call records, attachment metadata, thread
information, and user profile data.


SQLCipher Encryption
The Signal.sqlite database is encrypted using SQLCipher. Successful decryption
requires correct PRAGMA configuration parameters.

The following configuration was required in this analysis:
PRAGMA key = “x'{key_hex}'”;
PRAGMA cipher_page_size = 4096;
PRAGMA kdf_iter = 256000;
PRAGMA cipher_hmac_algorithm = HMAC_SHA512;
PRAGMA cipher_kdf_algorithm = PBKDF2_HMAC_SHA512;
PRAGMA cipher_plaintext_header_size = 32;
Key Observations

  • The first 32 bytes of the database are plaintext (header).
  • The database uses PBKDF2-HMAC-SHA512 with 256,000 iterations.
  • HMAC validation is enabled using SHA512.
  • Page size is 4096 bytes.
    Once decrypted, the database can be queried using standard SQLite methods.
screenshot 2026 03 02 at 9.42.20 am

Figure 2: Unencrypted Signal.sqlite header.

Once the correct key and parameters are applied, the database becomes accessible for
standard SQL querying.
The decryption key was recovered from a full file system extraction. In this instance, the key
material was decoded from the keychain.plist artefact.

screenshot 2026 03 02 at 9.42.58 am

Figure 3: Signal. SQLite cipher key obtained form keychain.plist

Message Records – model_TSInteraction
The table model_TSInteraction contains the primary message records. This table
stores:

  • Message text
  • Timestamps (UNIX epoch in milliseconds)
  • Thread identifiers
  • Call-related metadata
  • Message classification values
    Table ‘model_TSInteraction’ column values are shown below:
screenshot 2026 03 02 at 9.43.48 am
bplist

Figure 3: deserialised Bplist with ‘recipientAddressStates’ value.

screenshot 2026 02 15 201940

Figure 5: deserialised Bplist with ‘infoMessageUserInfo’ value.

Call Artefacts
Signal stores call information across two locations:

  • model_TSInteraction.callType
    Stores call-related message indicators.
  • CallRecord Table
    Stores structured call log data, including:
  • type (voice, video, group)
  • direction (incoming/outgoing)
  • status (answered, declined, missed)
    The column values of callRecord table are as below:
screenshot 2026 03 02 113630

Attachments
Table: MessageAttachmentReference
This table links messages to attachment records.


Table ‘MessageAttachmentReference’ contains details about the attachments:

screenshot 2026 03 02 134729

User information
Table ‘model_OWSUserProfile’ stores signal users’ information.

screenshot 2026 03 02 134845

Chat Threads
Table ‘model_TSThread’ stores information about chat threads.

screenshot 2026 03 02 134931


Attachment
Table ‘Attachment’ stores information regarding the attachment files.

screenshot 2026 03 02 135103

Attachment decryption process
Attachments are encrypted using AES-256-CBC.
Each attachment record contains a 64-byte encryption key:

  • First 32 bytes → AES key
  • First 16 bytes of encrypted file → IV
    Decryption workflow:
  1. Extract encryption key from Attachment.encryptionKey
  2. Separate AES key (first 32 bytes)
  3. Extract IV from encrypted file header
  4. Decrypt using AES-256-CBC
  5. Validate output using known file signatures (magic bytes)
    SQL Query for signal. SQLite can be downloaded from: ardfr/signal-ios-parser: Signal iOS SQLCipher parser with HTML reporting and attachment decryption.
    The following query consolidates:
  • Messages
  • Threads
  • Attachments
  • Call records
  • Author information


iOS Signal Decoder – Custom Python Parser
To streamline this process, I developed a custom Python based iOS Signal Application Parser.
Capabilities are:

  • Accepts encrypted Signal.sqlite
  • Accepts recovered SQLCipher key
  • Applies required PRAGMA parameters
  • Executes structured extraction queries
  • Generates:
  • HTML reports
  • CSV exports
  • Decrypted attachment files

Forensic Analysis of Microsoft.ZuneMusic_8wekyb3d8bbwe (Windows Media Player)
An unrecognizable person with binary code projected, symbolizing cybersecurity and digital coding.

Forensic Analysis of Microsoft.ZuneMusic_8wekyb3d8bbwe

Author: Arun KALACKATTU HARI (03/03/2026)

Modern Windows systems utilise packaged applications built on the Universal Windows Platform (UWP) framework. One such application is Windows Media Player (legacy Groove-based version), whose package identity is:

“Microsoft.ZuneMusic_8wekyb3d8bbwe”

The suffix:

“8wekyb3d8bbwe”

is Microsoft’s publisher ID, commonly seen across many built-in Microsoft Store applications.

Although the branding evolved from Zune Music to Groove Music, and later to the redesigned Windows Media Player in Windows 11, the underlying package identity remained unchanged for compatibility and update continuity.

Application Overview

Windows Media Player (UWP version) is designed to:

  • Play audio and video files
  • Automatically index media folders
  • Create and manage playlists
  • Display album and video metadata
  • Track recently played content

All configured music and video folders on the local machine are automatically indexed and displayed within the application library.

User Data Location

User-specific data for this application is stored at:

C:\Users\<user-name>\AppData\Local\Packages\Microsoft.ZuneMusic_8wekyb3d8bbwe


Folder structure within this directory is:

med1


Within this directory, the primary forensic artefacts reside in:

“LocalState”

Forensic Value of Microsoft.ZuneMusic_8wekyb3d8bbwe

From an investigative perspective, this package may provide:

  • Indexed media file paths
  • Media metadata (artist, album, title)
  • Playback timestamps
  • Recently played files
  • Cached thumbnail images
  • Video library folder references
Key Artefact: MediaPlayer.db

The primary database artefact is:

‘MediaPlayer.db’

This is an SQLite database located within:

‘LocalState’

It contains structured tables relating to indexed and recently played media.

AppState.json

Another important artefact is:

‘AppState.json’

This json file stores metadata relating to the most recent application activity, including:

  • Last opened file
  • Playback position
  • Application state at closure

For example, if a video named 0019.MTS is opened in media player and paused at 10 seconds, the JSON file records (shown in figure below):

  • The source file path
  • Playback progress timestamp
media2

This artefact can be useful in establishing:

  • Exact playback position
  • Whether the file was actively viewed
  • Last interaction with the application
MediaPlayer.db – Table Analysis
1. Table ‘File’

The File table stores information relating to recently played media files.

ColumnDescription
UriFull file path including file name
IdUnique identifier linked to the RecentlyPlayed table

Analysis indicates that this table stores up to 25 last played files.

2. Table ‘RecentlyPlayed’

This table records playback activity.

ColumnDescription
IdUnique identifier linked to File table
ItemType‘4’ = Audio file
‘5’ = Video file
PlayedTimeLast played timestamp (Microsoft ticks format)

The PlayedTime value is stored in Microsoft ticks (100-nanosecond intervals since 1 January 1601 UTC).

Analysis suggests this table stores 29 recently played entries, including both audio and video content.

3. Album and Media Tables

The Album table reflects the album listings displayed on the Media Player home page.

This table is populated when:

  • A user adds a folder containing media files
  • The application indexes the contents of that folder
media3

4. Adding a Folder to the Video Library

When a user adds a folder to the Video Library:

  • The media files within that folder are indexed
  • The Video table in MediaPlayer.db is populated
  • Corresponding entries appear in the application interface

5. Table ‘Video’

The Video table includes:

ColumnDescription
UriFull video file path
ParentFolderIdIdentifier linking to video folder table
ItemsCountNumber of media items within the folder

SQL Query to find recently palyed files is:

“”SELECT

File.Uri,

datetime(

(RecentlyPlayed.PlayedTime / 10000000.0) – 62135596800,

‘unixepoch’

) AS PlayedTime_UTC

FROM File

JOIN RecentlyPlayed

ON File.Id = RecentlyPlayed.Id

ORDER BY PlayedTime_UTC ASC;””

LocalCache

This directory contains cached image artefacts generated by the application, including:

  • Album artwork
  • Video thumbnails
  • Preview frames
  • Media tile images

These images are generated when:

  • A folder is added to the media library
  • A media file is indexed
  • A video is opened or previewed
  • The media grid view renders thumbnails

Cached files are located within ‘LocalCache\Image’ as shown below:

media4

Analysis showed that the filenames follow this path:

“”<Hash>-<Variant>-<Width>-<Height>””

For example:

0A-B0-86-2D-CD-66-43-7D-2A-45-19-87-54-C2-A8-F8-80-E4-D3-03-B6-A7-71-82-FF-1B-C0-23-ED-F8-05-AA-0-512-512.

The first 32 bytes of the file name is the sha256 of the normalized_media_identifier/uri.

The cache file names are cerated using the fucntion:

“SHA256(URI_string_UTF8)→ dash-separated hexadecimal→ append “-0-<width>-<height>””

To support validation and correlation, I have developed a tool that analyses URI values across MediaPlayer.db and links them to cache files located in LocalCache\Image. This enables deterministic verification of cache filename to media relationships.

This tool is available on my GitHub repository: ardfr/mediaplayer-localcache-cachekey: Deterministically correlates Windows Media Player LocalCache