Accounts Vault Crypto
Full cryptographic specification for Optserv Account Sharing — PBKDF2 key derivation, AES-GCM payload encryption, RSA-OAEP key sharing.
This page documents the full cryptographic model used by Optserv Account Sharing. It is the authoritative technical reference for how credentials are protected.
For the operational perspective, see Account Sharing Security Model.
Design goals
- Zero knowledge at rest — Optserv's servers never store or transmit plaintext credentials
- Per-item key isolation — each shared credential has its own encryption key; compromising one key doesn't expose others
- Cryptographic access revocation — removing someone from a shared item's access list actually revokes their ability to decrypt, not just their UI access
- Standard algorithms — no proprietary crypto; all algorithms are NIST-approved
Cryptographic layers
Layer 1: Key derivation — PBKDF2 + SHA-256
Each user has a master key derived from secret material using PBKDF2:
DerivedKey = PBKDF2(
PRF: HMAC-SHA-256,
Password: [user secret],
Salt: [user-specific salt],
Iterations: 210,000,
KeyLength: 256 bits
)
Iterations: 210,000 — This is aligned with the OWASP recommendation for PBKDF2-HMAC-SHA256 as of 2023. The high iteration count makes offline brute-force attacks computationally expensive.
The derived key is used to protect the user's private RSA key (see Layer 3).
Layer 2: Payload encryption — AES-GCM 256-bit
Each credential payload is encrypted with a unique AES-GCM key:
Algorithm: AES-GCM
Key size: 256 bits
Key: Randomly generated per item (ItemKey)
Output: { ciphertext, iv, authTag }
AES-GCM provides both confidentiality (encryption) and integrity (authentication). A tampered ciphertext fails authentication — data cannot be silently corrupted.
The authTag detects any modification to the ciphertext after encryption. If the ciphertext has been tampered with, decryption fails and the client rejects the data.
Layer 3: Key sharing — RSA-OAEP + SHA-256
To share an item with another user, the ItemKey is encrypted with the recipient's RSA public key:
Algorithm: RSA-OAEP
Hash: SHA-256
Input: ItemKey (256-bit AES key)
Recipient key: Recipient's RSA public key
Output: EncryptedItemKey (stored per recipient in the access list)
Each entry in an item's access list contains an independently encrypted copy of the ItemKey:
AccessList: [
{ userId: "alice", encryptedItemKey: RSA-OAEP(ItemKey, alice.publicKey) },
{ userId: "bob", encryptedItemKey: RSA-OAEP(ItemKey, bob.publicKey) },
]
To revoke access: delete the recipient's entry from the access list. Without their encrypted ItemKey, they cannot derive the AES key and cannot decrypt the payload.
Key lifecycle
| Event | What happens |
|---|---|
| User account created | RSA key pair generated; private key encrypted with derived key |
| User shares an item | ItemKey wrapped with recipient's public key; entry added to access list |
| User removed from access list | Their encrypted ItemKey entry deleted |
| User offboarded | RSA private key becomes inaccessible; items they owned flagged for re-keying |
What Optserv stores
| Data | Stored? | Readable by Optserv? |
|---|---|---|
| Plaintext credentials | No | No |
| Encrypted credential payload | Yes | No (no AES key) |
| User RSA public key | Yes | Yes (public key — not a secret) |
| User RSA private key (encrypted) | Yes | No (encrypted with derived key) |
| Encrypted item keys (per recipient) | Yes | No (RSA private key required) |
Optserv's servers hold ciphertexts and public keys only. All sensitive secrets remain encrypted with keys that Optserv does not possess.