Docs

Encryption

KeyPears uses AES-256-GCM (NIST SP 800-38D) for all symmetric encryption. AES-GCM is an authenticated encryption mode (AEAD) that produces ciphertext and an authentication tag in a single pass — no separate MAC is required. Two encryption modes are used.

Message encryption (ECDH)

When Alice sends a message to Bob, she computes a shared secret via elliptic-curve Diffie-Hellman on the NIST P-256 curve:

S = SHA-256(ECDH(alice_private_key, bob_public_key))

Here ECDH(a, B) is the 32-byte big-endian x-coordinate of the shared point a·B, as returned by the Web Crypto crypto.subtle.deriveBits API — not the 33-byte SEC1 compressed encoding. Both parties must hash the same raw coordinate for their derived keys to agree; mixing the two forms produces different keys and silent decryption failures.

The message payload is encrypted with AES-256-GCM using S as the key. Both Alice's and Bob's public keys are stored alongside the ciphertext, so that either party can re-derive the shared secret after key rotation.

The recipient computes the same shared secret using their own private key and the sender's public key:

S = SHA-256(ECDH(bob_private_key, alice_public_key))

This produces the identical shared secret due to the commutativity of ECDH.

Vault encryption

The vault stores secrets — passwords, credentials, and notes — encrypted under a vault key derived from the user's P-256 private key:

K_vault = HMAC-SHA-256(private_key, "vault-key")

The second argument is a fixed domain-separation string. Each vault entry is independently encrypted with AES-256-GCM under K_vault.

The server stores ciphertext alongside user-provided plaintext labels (name and search terms) to enable server-side search without revealing secret content.

AES-256-GCM format

AES-256-GCM produces authenticated ciphertext in the following format:

[Nonce (12 bytes)] || [Ciphertext] || [Auth tag (16 bytes)]
  • The nonce is randomly generated for each encryption operation and prepended to the output.
  • The authentication tag is produced by GCM itself and appended to the ciphertext.
  • Decryption verifies the auth tag as part of the GCM operation. If the tag does not match, decryption fails with an error — no separate MAC check is required.

Message structure

Each message stored on the server contains:

FieldDescription
senderAddressFull address (e.g. alice@acme.com)
encryptedContentAES-256-GCM-encrypted message content
senderPubKeySender's public key at time of sending
recipientPubKeyRecipient's public key at time of sending

Both public keys are stored so the recipient knows which keys to use for ECDH decryption, even after key rotation.