Security
Zero-knowledge. Provably.
Every architectural decision was made to ensure that a complete server breach cannot expose your passwords. Here is exactly how it works.
The vault encryption model
One master password. Two keys. Complete separation of authentication and encryption.
Step-by-step vault encryption
Master password
Typed by user. Never stored, never transmitted.
PBKDF2
600,000 iterations · SHA-256 · 16-byte random salt per user
authKey
→ Server. bcrypt-hashed. Authenticates sessions. Cannot decrypt vault.
encKey
→ Browser only. Non-extractable CryptoKey. Never transmitted.
AES-256-GCM
12-byte random IV per item · authenticated encryption · tamper-proof
Server stores: encrypted blobs only
PBKDF2 key derivation
- 600,000 iterations — exceeds NIST SP 800-132 minimum by 12×
- SHA-256 pseudo-random function
- 16-byte cryptographically random salt, unique per user
- Derives 256-bit auth key and 256-bit enc key in single pass
AES-256-GCM encryption
- 256-bit key — quantum-resistant for current threat models
- GCM mode provides authenticated encryption (AEAD)
- 12-byte random IV generated fresh per encryption operation
- IV prepended to ciphertext, stored as single base64 blob
- Authentication tag prevents ciphertext tampering
Web Crypto API
- All crypto operations run in browser via SubtleCrypto
- encKey created as non-extractable CryptoKey — JS cannot read raw bytes
- No third-party crypto libraries — native browser implementation
Share link cryptography
The decryption key is part of the URL but never sent to our server. This is a browser security guarantee, not a trust assumption.
Share link anatomy:
a3f9c2d1-4e5b-6789-0abc-def123456789#K3mN9pQ2rS5tU8vX1yZ4wA7bC0dE6fG
Sent to server (path)
UUID used to look up the encrypted blob in database
Never sent (fragment)
RFC 3986: browsers exclude fragment from HTTP requests
Why the fragment?
RFC 3986 specifies that the fragment identifier (everything after #) is processed by the browser only and is never included in HTTP requests. This is not a CredentialBase convention — it is a fundamental property of how URIs and HTTP work. Our server receives requests like GET /api/v1/share/uuid with no fragment.
PIN protection
Optional PIN adds a second factor. Client SHA-256 hashes the PIN before sending it to the server for verification. Server stores only the hash. Even if the share record is stolen from the database, the PIN is not stored in plaintext.
Expiry enforcement
Share links are checked server-side against expiresAt on every request. Expired shares are rejected and automatically purged from the database on a 6-hour cleanup cycle.
What CredentialBase can and cannot see
We can see
- Your email address
- Encrypted vault item blobs
- Session metadata (device name, IP, last active)
- Share link UUIDs and expiry times
- Encrypted share content
- Account creation and login timestamps
We cannot see
- Your master password (ever)
- Your encryption key (never leaves browser)
- Decrypted passwords or usernames
- Decrypted note contents
- Decrypted card numbers or CVVs
- Share link decryption keys (in URL fragment)
- Decrypted URLs associated with vault items
Threat model
Honest about what CredentialBase protects against — and what it does not.
Start today
Your passwords deserve better.
Free forever. Upgrade when you need unlimited. Zero-knowledge from day one.