Security

How HexVault Protects Your Passwords

Zero-knowledge architecture Last updated: March 2026

01/Overview

The core guarantee

HexVault is zero-knowledge. Your passwords are encrypted on your device before they reach our servers. We store only ciphertext. Without your master password, our database is useless to anyone — including us.

AES-256
Encryption
GCM
Mode
250K
PBKDF2 Iterations
96-bit
Random IV
TLS 1.2+
Transport
k-anon
Breach Check

02/Encryption standard

All vault data is encrypted using AES-256-GCM (Advanced Encryption Standard, 256-bit key, Galois/Counter Mode). GCM provides both confidentiality and authenticity — it detects if ciphertext has been tampered with, in addition to keeping the plaintext secret.

Each vault entry is encrypted independently with its own random 96-bit initialisation vector (IV). This means that even if two entries have identical content, their ciphertext will be different.

Why independent IVs matter

Reusing IVs in GCM is catastrophic for security. HexVault generates a cryptographically random IV for every single encryption operation using the browser's crypto.getRandomValues() API, which uses the operating system's entropy source.

03/Key derivation

Your master password is never transmitted to our servers. Instead, it is used to derive an encryption key locally in your browser:

// All of this happens in your browser only const salt = crypto.getRandomValues(new Uint8Array(32)) const keyMaterial = await crypto.subtle.importKey("raw", encoder.encode(masterPassword), ...) const encryptionKey = await crypto.subtle.deriveKey( { name: "PBKDF2", salt, iterations: 250000, hash: "SHA-256" }, keyMaterial, { name: "AES-GCM", length: 256 }, ... )

We use PBKDF2 (Password-Based Key Derivation Function 2) with 250,000 iterations and SHA-256. The high iteration count makes brute-force attacks computationally expensive. A unique random salt is generated per account and stored alongside the ciphertext.

The derived encryption key exists only in memory during your session. It is never written to disk, never transmitted over the network, and is discarded when you lock your vault or close the tab.

04/Vault entry encryption

Every vault entry — password, username, URL, notes — is encrypted as a single JSON object before transmission:

// Entry data is serialised and encrypted together const iv = crypto.getRandomValues(new Uint8Array(12)) const plaintext = JSON.stringify({ title, username, password, url, notes }) const ciphertext = await crypto.subtle.encrypt( { name: "AES-GCM", iv }, encryptionKey, encoder.encode(plaintext) ) // Only { ciphertext, iv } is sent to the server

What we store in our database is { ciphertext, iv }. Without the encryption key — which only exists in your browser — this data is meaningless.

05/Breach monitoring

HexVault checks your passwords against the Have I Been Pwned database of billions of compromised credentials. This is done using the k-anonymity model:

  • Your password is hashed locally using SHA-1
  • Only the first 5 characters of that hash are sent to the HIBP API
  • The API returns all hash suffixes matching those 5 characters (typically hundreds)
  • Your browser checks locally whether your full hash appears in the returned list
  • Your actual password never leaves your device
Why SHA-1 for breach checking?

SHA-1 is used here purely for breach lookup compatibility with the HIBP API — not for security. The actual vault encryption uses AES-256-GCM with PBKDF2-derived keys. The SHA-1 hash of your password is never stored anywhere.

06/Transport security

All traffic between your browser and HexVault's servers is encrypted using TLS 1.2 or higher. HTTP requests are automatically redirected to HTTPS. HexVault enforces HSTS (HTTP Strict Transport Security) to prevent downgrade attacks.

Traffic is proxied through Cloudflare, which provides additional DDoS protection and terminates TLS at the edge. The connection from Cloudflare to our origin server is also encrypted.

07/Infrastructure

  • Application servers run in isolated Docker containers
  • The database is not publicly accessible — only reachable from the application container on an internal network
  • Encrypted backups are taken automatically
  • No plaintext password data ever touches our infrastructure
  • Security headers are set on all responses: CSP, HSTS, X-Frame-Options, X-Content-Type-Options

08/Two-factor authentication

HexVault supports TOTP (Time-based One-Time Password) two-factor authentication, compatible with any standard authenticator app. We strongly recommend enabling 2FA on your account.

2FA protects against unauthorised access even if your email and password are compromised. It does not affect the zero-knowledge encryption of your vault — your master password remains the sole decryption key.

09/Session security

  • Auto-lock. Vault automatically locks after a configurable period of inactivity. The encryption key is discarded from memory on lock.
  • Trusted devices. New device logins trigger a security notification email.
  • Session tokens. Authenticated sessions use secure, httpOnly cookies. Session tokens are rotated on each login.
  • Concurrent sessions. You can view and revoke active sessions from account settings.

10/Audit & responsible disclosure

Audit status

HexVault is currently in early access. A formal third-party security audit is planned before public launch. This page will be updated with audit results when available.

We welcome responsible disclosure of security vulnerabilities. If you find an issue, please contact us before public disclosure to give us time to investigate and fix it.

Responsible disclosure

Email: [email protected]

Please include a clear description of the vulnerability, steps to reproduce, and your assessment of impact. We will respond within 5 business days.

We ask for a minimum of 90 days before public disclosure to allow time for investigation and remediation.