How KeyLockr encrypts your data

Two interactive diagrams show where every key lives and what happens to a single password between the moment you type it and the moment you read it back. The jargon is not hidden: hover or tap any box or arrow for the plain-language version.

The short version

Secret keys are created locally

The phone (Safe) creates the Account Key and its own device keys. Each AP creates its own device keys, and the editing device creates the fileKey for a new entry. Secret keys are not generated by the server or uploaded in plaintext.

It is locked before it leaves

The body of an entry is sealed on the device, and so are fields like the title and the URL. What travels is already an unopenable blob — nothing is encrypted "after arrival".

Your computer gets a granted copy

The macOS app and Chrome extension cannot approve another device or service or expand their own scope. Your phone seals content keys into envelopes only that device can open; revocation stops future access but does not erase keys or plaintext it already obtained.

Who holds which key

This is a holdings map, not a timeline: it answers where things sit and which key wraps which. Click any box or arrow for the full story; press Esc to close.

Key holdings map Secret keys are generated locally by the devices that use them; the server receives encrypted vault fields, sealed envelopes, public keys, and operational metadata.

One password, end to end

The same system as a timeline: from your keystrokes, through two layers of encryption and the cloud, to a second device reading it back.

Data flow Plaintext exists on your phone and on your computer — at no point in between.

Specifications

What follows is the actual implementation, not an illustration. Algorithm names, lengths, and field names match the code.

Item Specification
Symmetric encryption secretbox — XSalsa20-Poly1305
Asymmetric encryption (envelopes) box — Curve25519 (X25519) + XSalsa20-Poly1305
Signatures Ed25519 (the seal on every KPS frame)
Account Key (AK) 32 bytes, one per account, generated on the phone.
fileKey One independent key per entry, used only to seal that entry's body.
Content format data_encrypted = [24B nonce] || secretbox(plaintext, fileKey, nonce)
Nonce rule A fresh random 24-byte nonce on every single write, never reused. It rides in the clear at the front — a nonce is not a secret.
Integrity tag Poly1305, 16 bytes. Alter one byte and verification fails; the data is rejected, not silently accepted.
Reading older entries Ciphertext shorter than 40 bytes is never treated as the current format. On read, the current format is tried first and the older one only after the tag fails — a trial-decrypt, with no flag trusted.
Lightly encrypted fields The title, URL, 2FA label, and tags live in data_plain, encrypted with the Account Key. The field name is historical — the contents are not plaintext. The server passes them through opaquely.
Per-device envelope data_filekey = box(fileKey, apEncPk, safeEncSk) + nonceForKey
Account key for a device account_key_for_ap = box(AK, apEncPk, safeEncSk)
Self-recovery recovery_meta.account_key = secretbox(AK, encSk) — the server cannot open it.
Binding uniqueness (safe_id, app_tag, sign_pk)
Versioning and concurrent writes Every entry carries a ver counter. A write via app_set_data supplies the expected ver as a CAS check; if it changed meanwhile the server answers file_ver_conflict instead of overwriting.
Backups Automatic backups are kept for 7 days and hold exactly the same ciphertext — still sealed with the Account Key and the fileKeys.

Threat model

Every claim below maps to a line in the specification table above. None of it is marketing language.

Server breach or database leak

What an attacker gets: AK-encrypted metadata, fileKey-encrypted content, box envelopes, and public keys.

No master password exists on the server, and no private key capable of opening vault data is stored there. The backups hold the same ciphertext.

Eavesdropping or a machine in the middle

Frames on the wire are already ciphertext, wrapped in an Ed25519 signature. Change one byte and both the signature and the Poly1305 tag fail.

The point is not that TLS exists; it is that stripping TLS still leaves content that cannot be read or altered.

A third-party app over-reaching

A binding is unique on (safe_id, app_tag, sign_pk), capabilities are limited to sso, app_data, and ap, and the phone approves each one.

An app without the matching envelope cannot open the ciphertext even if it holds it. Details on the SSO page.

What we do not claim to stop
  • A device that is already unlocked, with someone sitting in front of it.
  • A device under the control of malware — whatever is on the screen is visible to it too.
  • Content the user copies out to somewhere else.

Glossary

secretbox One shared key both locks and unlocks, with a tamper-detecting tag attached.
box An envelope addressed to one public key: only the device holding the matching private key can open it.
nonce A number used exactly once. Reusing one with the same key makes both messages readable, which is why a fresh one is drawn per write.
Account Key (AK) The account-wide key. It covers metadata and the recovery blob.
fileKey A content key belonging to a single entry and shared with no other.
Safe Your phone. The Account Key and the Safe's own keys are created here, and device authorizations are approved here.
AP (Access Point) A consumer such as the macOS app or the Chrome extension. The phone grants its access and the phone takes it back.
KPS KeyLockr Protocol Suite — the frame format devices speak, always signed on the outside.