Key Derivation
Argon2id
Memory-hard · 64 MB · 3 iter · 4 threads
Cipher
AES-256-GCM
Authenticated encryption · unique IV per entry
Architecture
Zero-knowledge
Master password never transmitted or stored
Vault salt
256-bit random
Unique per user · never reused
Entry salt
Per-entry
Additional random salt per password entry
Transport
TLS 1.3
HSTS enforced · Cloudflare CDN
Breach checks
k-Anonymity
Only a 5-char hash prefix ever leaves your device
01 — How it works

End-to-end in three steps

HexVault's security model is simple enough to explain in three steps and strong enough to withstand a server breach.

1
You enter your master password
Your master password never leaves your browser. It passes through Argon2id — a memory-hard KDF — combined with a 256-bit salt retrieved from the server. This produces a 256-bit encryption key marked non-extractable by the Web Crypto API, meaning no JavaScript can read it back out once created.
2
Every password is encrypted in your browser
Each vault entry is encrypted independently using AES-256-GCM with a fresh random 96-bit IV. The ciphertext and IV are stored server-side. The encryption key stays only in your browser's memory and is destroyed on logout.
3
The server stores only what it cannot read
HexVault's server stores base64(ciphertext) and base64(IV). It has no access to your master password, encryption key, or plaintext passwords — ever. A full database dump yields only ciphertext that is computationally infeasible to decrypt without your master password.
Encryption flow
Master password
Browser only
Argon2id KDF
64 MB · 3 iter
256-bit key
Non-extractable
AES-256-GCM
Authenticated
Server storage
Ciphertext only
What this means in practice: if HexVault's servers were breached, subpoenaed, or seized, the attacker receives only AES-256-GCM ciphertext. Without your master password — which never left your device — decrypting it is computationally infeasible.
02 — Key Derivation

Argon2id — why we chose it over PBKDF2

Your master password passes through Argon2id — winner of the 2015 Password Hashing Competition, designed specifically to resist GPU and ASIC brute-force attacks.

Why not PBKDF2? 1Password and Bitwarden use PBKDF2-SHA256. Because PBKDF2 is CPU-only, a modern GPU cluster can test billions of guesses per second. Argon2id requires 64 MB of memory per attempt — making parallel GPU attacks roughly 1,000× more expensive per guess.
ParameterValueWhy
AlgorithmArgon2idHybrid: side-channel resistant + GPU resistant
Memory cost65,536 KiB (64 MB)OWASP 2023 minimum for interactive logins
Time cost3 iterations~500 ms on modern hardware
Parallelism4 threadsMatches typical device core count
Output32 bytes (256 bits)Exact key material for AES-256
Salt256-bit random, per userPrevents precomputation; unique per account
JavaScript · deriveKey() · static/script.js
async function deriveKey(masterPassword, vaultSalt) {
  const salt = Uint8Array.from(atob(vaultSalt), c => c.charCodeAt(0));
  const result = await argon2.hash({
    pass: masterPassword, salt,
    type: argon2.ArgonType.Argon2id,
    mem: 65536, time: 3, parallelism: 4, hashLen: 32,
  });
  return await crypto.subtle.importKey(
    'raw', result.hash,
    { name: 'AES-GCM', length: 256 },
    false, ['encrypt', 'decrypt']
  );
}
03 — Vault Encryption

AES-256-GCM with a unique IV per entry

Every password is encrypted independently with a fresh random 96-bit IV. Reusing an IV with the same key would be catastrophic — so we never do it.

PropertyValueNotes
ModeAES-256-GCMAuthenticated encryption — tampering is detected and rejected
Key length256 bitsMaximum AES key size; 2²⁵⁶ keyspace
IV96 bits, random per entryVia crypto.getRandomValues(); stored alongside ciphertext
Auth tag128 bitsCryptographic proof ciphertext has not been modified
Crypto APIWeb Crypto (browser-native)OS-level; no third-party crypto library
The GCM auth tag means any single bit-flip in the ciphertext causes decryption to fail. Your browser will refuse to display tampered entries rather than silently showing corrupted data.
04 — Breach Monitoring

k-Anonymity — your passwords never leave your device

HexVault checks against 12 billion+ compromised credentials via Have I Been Pwned. Your actual passwords are never transmitted — only a partial hash.

HexVault computes a SHA-1 hash of your password entirely in your browser. Only the first five characters of that hash are sent to HIBP. The server responds with every matching suffix (~500 results). HexVault checks locally whether your full hash is in that list.

HIBP receives 5 hex characters out of 40 — 1/2²⁰ of the full hash. That is mathematically insufficient to determine which password you queried.

Privacy guarantee: this is the same k-anonymity model used by 1Password and Bitwarden, and is the accepted best-practice for breach-checking services.
05 — Secure Sharing

How password sharing works

Two sharing models — user-to-user and one-time secure links — both preserving zero-knowledge within the constraints of shared secrets.

U
User-to-user sharing
The password is re-encrypted under the recipient's vault key before storage. The recipient's client decrypts it using their own master-password-derived key. The server never holds both parties' plaintext at the same time.
L
One-time share links
Cryptographically random token, time-limited and view-count-limited. Once expired or consumed, the token is deleted. The plaintext is only visible to whoever holds the URL during the valid window.
Honest caveat: sharing inherently means the recipient has a copy. This is true of all password managers — HexVault makes the scope and expiry of that access explicit and revocable.
06 — Transport & Infrastructure

Encrypted in transit, hardened at rest

TLS 1.3 via Cloudflare on all connections. Full security controls applied to every request.

ControlImplementation
TLS1.3 minimum · TLS 1.0/1.1 disabled via Cloudflare
HSTSmax-age=31536000; includeSubDomains
CSPscript-src 'self' 'wasm-unsafe-eval' — no unsafe-inline
DatabasePostgreSQL · vault entries stored as base64 AES-256-GCM ciphertext
Session cookiesHttpOnly · Secure · SameSite=Lax · auto-expire on inactivity
Auth passwordsbcrypt with per-user salt · separate from vault encryption
Rate limitingLogin: 10 attempts / 15 min · account lockout after threshold
Two-factor authTOTP (RFC 6238) · WebAuthn / FIDO2 hardware keys
CSRFPer-session token on all state-changing requests
Data jurisdictionUK-based · GDPR compliant
07 — Two-Factor Authentication

TOTP, WebAuthn, and replay protection

HexVault supports two independent 2FA mechanisms, both with active replay attack prevention.

T
TOTP (RFC 6238)
Time-based one-time passwords with a 30-second window. Each code is single-use — the server records the last accepted code and timestamp. Any attempt to reuse a code within a 90-second window is rejected, preventing replay attacks even when a code is intercepted in transit.
W
WebAuthn / FIDO2
Hardware security keys and platform authenticators (Face ID, Windows Hello, Touch ID) via the Web Authentication API. Private key material never leaves the authenticator. Phishing-resistant by design — the credential is scoped to the origin and cannot be used on a fake domain.
PropertyTOTPWebAuthn
StandardRFC 6238 / HOTPFIDO2 / W3C WebAuthn
Replay protectionCode + timestamp logged server-sideChallenge-response — no reusable secrets
Phishing resistancePartial (code can be relayed)Full — origin-bound credential
Stored server-sideEncrypted TOTP secretPublic key only
08 — Session Security

How sessions are protected

HexVault uses server-side sessions with multiple layers of protection against hijacking and fixation.

ControlImplementationWhy it matters
Cookie flagsHttpOnly; Secure; SameSite=LaxPrevents JS access and CSRF; HTTPS-only transmission
Session storageServer-side (Redis)Session data never sent to client — token only
CSRF tokensPer-session, checked on all state-changing requestsPrevents cross-origin forged requests
IP bindingOptional — triggers re-auth on IP changeLimits stolen-cookie utility
Inactivity timeoutConfigurable 15–480 min auto-lockLimits exposure window on unattended devices
Concurrent sessionsTracked per device — any can be revokedUser can terminate suspicious sessions immediately
Vault key in memoryNon-extractable CryptoKey; erased on logout/lockClosing the tab destroys the key — ciphertext at rest is safe
09 — Organisation Vault Cryptography

How team and enterprise vaults maintain separation

Org vaults use a symmetric group key distributed via ECDH key agreement — no member's personal vault key is ever exposed to the organisation.

1
Org key generation
When an organisation vault is created, a random 256-bit AES-GCM symmetric key is generated client-side. This is the org vault key — it encrypts and decrypts all shared credentials.
2
ECDH key grant
Each member generates an ECDH key pair. Their public key is uploaded. An admin wraps the org vault key with each member's ECDH public key and stores the result server-side. The org key can only be unwrapped by the corresponding private key — held only by that member's device.
3
Cryptographic separation
Personal vault passwords are encrypted with the user's personal key derived from their master password. Org vault credentials are encrypted with the org key. A compromised personal account does not expose org credentials, and leaving an organisation immediately invalidates the member's wrapped org key.
Offboarding: when a member is removed, their wrapped org key grant is deleted server-side. They cannot decrypt org vault entries they previously had access to — there is no grace period on the cryptographic access, only on data retention.
10 — Hash Migration

Upgrading legacy password hashes transparently

Early accounts used PBKDF2-SHA256 for auth password hashing. All accounts transparently migrate to bcrypt (cost 12) on next login.

On successful login, HexVault detects the hash algorithm used. If it is PBKDF2, the auth password is re-hashed with bcrypt cost-factor 12 and the stored hash is updated atomically. The user notices nothing. After migration, login verifies against bcrypt only.

Note that auth password hashing is entirely separate from vault encryption. Your vault remains AES-256-GCM regardless of which auth hash algorithm is in use.

AlgorithmWhen usedStatus
PBKDF2-SHA256Accounts created before v6.39.51Auto-migrates on login
bcrypt cost=12All accounts after migrationCurrent standard
11 — Verify It Yourself

Don't take our word for it

The functions on this page are the actual functions running in your browser. We don't minify our client-side code — inspect it at any time in DevTools.

Key derivation
deriveKey()
DevTools → Sources → script.js → search "deriveKey". Argon2id call exactly as documented.
Encryption
encryptPassword()
Search "encryptPassword" in script.js. AES-256-GCM and random IV generation are verbatim.
Breach check
checkPasswordBreach()
Search "pwnedpasswords.com". SHA-1 truncated to 5 chars before the API call.
Network
DevTools → Network
Filter /api/passwords. Request bodies show encrypted_password and iv — never plaintext.
12 — Comparison

How we compare

Argon2id's memory-hardness changes the economics of brute-force attacks fundamentally versus the PBKDF2 used by competitors.

FeatureHexVault1PasswordBitwardenLastPass
Key derivationArgon2idPBKDF2Argon2id / PBKDF2PBKDF2
GPU-resistant KDFYesNoOptionalNo
Memory-hard (64 MB default)YesNo19 MB defaultNo
CipherAES-256-GCMAES-256-GCMAES-256-GCMAES-256-GCM
Zero-knowledgeYesYesYesPartial
AI security assistantHexGuardNoNoNo
Auditable client codeUnminifiedNoPartialNo
JurisdictionUKCanadaUSUS
Public security docsThis pagePartialPartialNo
13 — Responsible Disclosure

Found a vulnerability?

We respond quickly to credible security findings. Please give us the opportunity to fix an issue before making it public.

Email [email protected] with description and reproduction steps. We acknowledge within 48 hours and aim to patch critical issues within 7 days.
In scope
hexvault.co.uk and subdomains
Authentication bypass
Encryption weaknesses
Vault data exposure
Session hijacking
CSRF or XSS vulnerabilities
Out of scope
Denial of service
Social engineering
Physical attacks
Third-party services
Clickjacking on non-sensitive pages
Issues in uncontrolled dependencies