Skip to main content

Encryption Details

Technical details about Docket's encryption implementation.

Cryptographic Standards

Password to Key: Argon2id

Your password is converted to an encryption key using Argon2id:

ParameterValue
AlgorithmArgon2id
Memory64 MiB
Iterations3
Parallelism4
Output256 bits
Salt128 bits (random, per-vault)

Why Argon2id?

  • Memory-hard: Resistant to GPU/ASIC attacks
  • Winner of the Password Hashing Competition
  • OWASP recommended

Database: SQLCipher

All structured data is stored in an encrypted SQLite database:

ParameterValue
AlgorithmAES-256-CBC
Page Size4096 bytes
KDFPBKDF2-HMAC-SHA512
HMACSHA512 per-page

Files: AES-256-GCM

Individual files are encrypted with authenticated encryption:

ParameterValue
AlgorithmAES-256-GCM
Key256 bits (random, per-file)
Nonce96 bits (random)
Auth Tag128 bits

File format:

[nonce: 12 bytes][ciphertext][auth_tag: 16 bytes]

Two-Layer Key System

┌─────────────────┐
│ Your Password │
└────────┬────────┘
│ Argon2id + salt

┌─────────────────┐
│ Derived Key │──────► Encrypts Database
│ (256 bits) │ (chats, metadata, file keys)
└─────────────────┘

│ Per-file keys

┌─────────────────┐
│ Random File Keys│──────► Encrypted Files
│ (256 bits each) │
└─────────────────┘

Benefits:

  • Password change only re-keys database, not all files
  • Each file has independent key (compromise isolation)
  • File keys are random (not derived from password)

Metadata Hiding

Files on disk reveal nothing about their contents:

On-disk filename:

f_a1b2c3d4e5f67890.enc

In encrypted database:

id: "abc123"
disk_filename: "f_a1b2c3d4e5f67890.enc"
original_name: "my-vacation-photo.jpg"
mime_type: "image/jpeg"
size: 2456789
encryption_key: [256-bit random key]

Benefits:

  • Original filename never visible on disk
  • File type not inferable from extension
  • Prevents targeted attacks based on filenames

Mode Switching

Enabling Encryption

  1. Enter new password
  2. Salt generated, key derived
  3. Database converted to SQLCipher
  4. Each file encrypted with random key
  5. Files renamed to random format

Disabling Encryption

  1. Verify current password
  2. Database converted to plain SQLite
  3. Each file decrypted
  4. Files renamed to original names
  5. Salt removed

Both operations are crash-safe with atomic writes.

Memory Security

Key Handling

  • Derived key kept in memory while unlocked
  • Key immediately zeroed on lock (using zeroize)
  • No key material written to disk

USB Disconnect

When the USB is disconnected:

  1. Drive disconnect detected (within 2 seconds)
  2. force_lock_vault() called
  3. Key zeroed from memory
  4. All sessions invalidated
  5. UI cleared of decrypted content

Browser Security

On lock:

  1. All blob URLs revoked
  2. React state cleared
  3. WebView reloaded (clears all memory)
  4. localStorage/sessionStorage cleared

Threat Model

Protected Against

ThreatMitigation
USB drive theftAll data encrypted at rest
Filesystem browsingNo plaintext secrets or files
Filename leakageRandom disk filenames
Weak password attacksArgon2id with 64MB memory cost
File tamperingAES-GCM authentication
Cold boot attackKeys zeroed on lock

Not Protected Against

ThreatReason
Malware on host PCApp runs with user privileges
Memory dump while unlockedKey must be in memory to decrypt
KeyloggerOutside app's control

Recommendations

  1. Use a strong password — Long, unique, not used elsewhere
  2. Lock when not in use — Click lock or remove the USB
  3. Use encrypted mode — Unless you have a specific reason not to
  4. Be careful on untrusted computers — Malware could capture your password