Technical whitepaper

Encryptio Zero-Knowledge Model

Where encryption happens, how keys are generated, which algorithms we use besides AES-256, and how account recovery works.

Version 1.0 · September 2026 · Describes product behavior, not a client-only end-to-end protocol.

1. Definition

Encryptio is zero-knowledge at rest: Postgres stores only vault, note, and key-backup ciphertext. The master key is never written to the database.

This is not client-only end-to-end encryption for vault items. At login the master key is derived from the password and held on the server for the session, so the web app and the extension API can decrypt data.

During an authenticated session the server can read vault plaintext. Without the password, recovery key, or an active session, a database copy alone is not enough to decrypt the vault.

2. Threat model

The useful question is not “can Encryptio ever decrypt?”, but “in which state does the server hold the master key?”.

Status Can the server read vault plaintext?
No login; ciphertext in Postgres No: the master key is not in the database
User signed in (web or extension) Yes: master key derived at login and held for the session
Password reset without recovery key No: the new master key does not open the previous ciphertext
Digital Legacy inactivity grant Yes, delegated, only if the owner enabled escrow

3. Where encryption happens

The encryption point depends on the data type. Shared files are encrypted in the browser before upload. Vault items are not: the application encrypts them when writing to the database.

Data Where it is encrypted What remains on the server
Vault passwords and notes Application server, on database write AES-GCM ciphertext only
Shared files Browser, before upload Encrypted blob on disk only
Internal sharing between Encryptio users Server: per-share AES key wrapped with the recipient RSA key Ciphertext and wrapped key
External sharing (link) Server, with a key derived from the link token Ciphertext and token hash
Extension local cache Extension service worker None: it stays on the device

The authenticated extension API returns vault items already decrypted. It is a secret channel between the session (or Bearer token) and the client, not a ciphertext dump.

4. Key generation

Login password and master key

At registration each account receives a 16-byte per-user salt. The password has two distinct uses:

  • Login verification: Argon2id hash (with an application pepper) stored as password_hash.
  • Master-key derivation: PBKDF2-HMAC-SHA256, 600,000 iterations, 256-bit output, from password + pepper + salt. This key is not persisted in Postgres.

After a successful login the master key stays in Redis, keyed by user and session, with a TTL (12 hours by default). It is never written to the Flask session cookie. Logout deletes the Redis key. Within a single request it is held only in the Flask g context.

Recovery key

At registration, and again on every authenticated password change, the server generates 32 random bytes (256 bits). The recovery key is shown once, in Base64. It encrypts a backup copy of the master key. The plaintext recovery key is not stored.

Other keys

  • Email: an AES key derived deterministically from the user identifier and a system secret, so login and reset remain possible without the master key.
  • Internal sharing: RSA-2048 key pair per user; the private key is encrypted with the recipient’s master key.
  • External sharing: AES key derived from the link token (the plaintext token is not in the database).
  • File share: AES key derived in the browser from the share password chosen by the user.

5. Algorithms besides AES-256

AES-256-GCM is the AEAD for the vault, notes, TOTP secrets, the master-key backup, and sharing payloads. Around it we use distinct primitives for authentication, key derivation, wrapping, and lookup.

Use Algorithm Parameters
Login password hash Argon2id time cost 3, memory 64 MiB, parallelism 4
Master key PBKDF2-HMAC-SHA256 600,000 iterations, 32 bytes, per-user salt and pepper
Vault, notes, blobs, key backup AES-256-GCM 96-bit nonce prepended to the ciphertext
Email lookup HMAC-SHA256 normalized address; separate email ciphertext
API, legacy, and external-share tokens SHA-256 hash only in the database, with a pepper
Internal sharing RSA-2048-OAEP SHA-256; wraps a per-share AES key
File share (browser) PBKDF2-HMAC-SHA256 + AES-256-GCM 100,000 iterations in the client, then ciphertext upload
Two-factor authentication TOTP secret encrypted at rest with the master key
Blockchain timestamp SHA-256 only the plaintext file digest, computed in the browser

6. Account recovery

Login-password reset and vault recovery are distinct operations. An email link proves you control the address, not that you hold the master key.

Reset with recovery key

  1. The user confirms the reset link and provides the recovery key.
  2. The server decrypts the master-key backup with that recovery key.
  3. With the previous master key it decrypts the vault, notes, and TOTP secret.
  4. From the new password it derives a new master key and re-encrypts everything.
  5. The backup is re-wrapped with the same recovery key. Email is not re-encrypted: it uses a key independent of the password.

Reset without recovery key

You can set a new password and sign in, but the new master key does not open the existing ciphertext. Vault data stays unreadable until you use the original recovery key to recover it, or it is lost.

Password change from an authenticated session

If you still know the current password, the server derives the master key, re-encrypts the data with the new master key, and issues a new recovery key to save in place of the previous one.

Other mechanisms, not equivalent

  • 2FA recovery codes unlock only the second factor, not the vault.
  • Digital Legacy can grant read-only access to an email contact after a waiting period. Master-key escrow for inactivity is explicit and opt-in.

Losing both the password and the recovery key means permanent loss of vault data. That is intentional: without one of those two proofs, nobody — including Encryptio — can reconstruct the master key from the database alone.

7. Related features

  • External shares: always time-limited, revocable by the sender; the email contains only the link, not the content.
  • Manifest V3 extension: local cryptography and API calls go through the service worker, not content scripts.
  • Chia timestamp: proof of existence of the hash, not an eIDAS timestamp and not a notary act.

8. What this model is not

We do not claim that “even Encryptio can never decrypt”. That sentence would describe a vault encrypted only in the browser, with a key that never leaves the device. Encryptio encrypts the vault at rest and decrypts in session to provide the web app, API, and account recovery.

The security value is this: an attacker with only the database (or a cold backup) does not get vault passwords. An attacker who compromises an application process during an active session is in the same perimeter as that session’s master key: that is why the key lives in Redis with a TTL, not in the cookie, and logout deletes it.

The Security page remains the summary for everyone. This whitepaper is the technical description of the model.

Want to use Encryptio with this key model?