Product Idea

Zero-Knowledge Encrypted Notes App

Build an encrypted notes app whose server stores only ciphertext: encryption happens on the client, keys never leave the device, and the zero-knowledge architecture is explained end to end.

Advanced

Zero-Knowledge Encrypted Notes App

A notes application architected so the server that stores your notes cannot read them: notes are encrypted on your device before they are saved, the encryption key never leaves your device, and the server stores only ciphertext plus minimal metadata. The project’s real deliverable is understanding and implementing that architecture — key derivation, authenticated encryption, key management, and an honest threat model — end to end, in a scope one developer can finish.

>“Zero knowledge” is a design goal, not a badge. Encryption is a tool, not a guarantee. This architecture is only as strong as its implementation, its key handling, and its review — and a student project has not been audited the way production security products have. Do not store highly sensitive secrets (passwords, recovery codes, identity documents) in an unverified personal project, and treat this build as a serious exercise in applied cryptography — not as a secure vault for real secrets.

How This Idea Relates to the Offline-First Notes App

The site already has an offline-first note-taking app with sync — and this project is deliberately not another version of it. The two solve different problems:

  • #029 focuses on reliability: notes must work offline and sync without data loss, using local-first storage and conflict handling. Its central question is “what happens when the network disappears or misbehaves?”
  • #045 focuses on confidentiality: notes must stay secret from the server operator and from anyone who breaches the server. Its central question is “what can the server see, and how do we make it see nothing?”

The architectures follow from those questions. #029 keeps a full local copy as the source of truth and treats sync as a robustness problem. #045 encrypts before anything leaves the device, treats the server as an untrusted storage bucket for ciphertext, and makes offline use optional rather than the defining feature. The two are natural cross-links — an advanced learner who has built #029 can reuse its sync intuition here — but the encryption design, not the offline story, is the heart of this project.

Who Is This For?

  • Developers who want to learn applied cryptography — key derivation, AEAD encryption, and threat modeling — by building rather than reading
  • Privacy-minded users who want a notes app whose server-side storage is provably unreadable to the operator
  • Advanced students ready to reason carefully about key management tradeoffs and metadata leakage

The Problem

Most “notes in the cloud” products can read your notes: the server holds the plaintext (or a key that decrypts it), which means the operator, a compromised employee, or a database breach can all access content. End-to-end-encrypted products exist but are closed, so there is no way to learn how the hard parts actually work — key derivation, encrypting metadata, recovery tradeoffs, and what “zero knowledge” really requires. This project makes that architecture legible: a small server that stores ciphertext and a client that never lets a key leave the device.

How It Works

1. Encryption Happens on the Client, Always

Plaintext exists only inside the user’s browser/device session. When a note is saved, the client encrypts it with a fresh data key and sends only the ciphertext to the server. The server’s database never contains a plaintext note or an encryption key.

2. Keys Are Derived, Not Stored

  • The user has an account password (or passphrase). It authenticates them and, separately, drives key derivation.
  • A key derivation function (PBKDF2 or Argon2 — implemented via an established library, never invented) turns the password plus a random salt into the user’s master key.
  • Each note gets its own random data key, and that data key is wrapped (encrypted) by the master key. This “envelope” pattern means one note can be re-encrypted or shared without touching the others, and a stolen database yields only wrapped keys.

3. The Server Is an Untrusted Ciphertext Store

The server stores: the wrapped key envelopes, the ciphertext, and the minimum metadata needed to function (a note id, a version, timestamps the user accepts). The server can authenticate the user (it holds a password verifier) but never the encryption key — authentication and encryption are deliberately separated. Anyone who reads the server database sees ciphertext and wrapped keys, and nothing that can decrypt them without the user’s password.

4. Encrypted Sync of Ciphertext

Notes sync as ciphertext blocks. Because each block is encrypted with a key only the client holds, the sync channel (even HTTPS) is a transport detail rather than a trust boundary: the interesting property is that the stored bytes are unreadable. Reusing the client-side conflict/ordering patterns from a sync build is fine here — the difference is the payload being synchronized is already encrypted.

5. Recovery Is a Tradeoff, Made Explicit

If the password is lost, the wrapped keys cannot be unwrapped and the notes are unrecoverable — that is the price of the server not holding keys. The app offers two honest options:

  • No recovery — simplest, most private; losing the password loses the notes.
  • A printable recovery key — a high-entropy backup that can unwrap the master key; the user stores it offline. This is a convenience that shifts risk back to the user, and the UI must say exactly that.

6. Metadata Minimization Is a Design Decision

Encrypting note titles and keeping only opaque ids means search-by-title happens client-side (the client decrypts titles on unlock and indexes locally). This is a real tradeoff — server-side search is impossible without leaking titles — and this project chooses the privacy side and documents the cost.

Threat Model

| Attacker | Can see | Cannot see |
|———-|———|————|
| Server operator / DB breach | Ciphertext, wrapped keys, timestamps, note count | Plaintext, keys, titles (if titles are encrypted) |
| Network eavesdropper | Encrypted transport | Plaintext (HTTPS + client-side encryption both apply) |
| Malicious server code | Everything the server sees (above) | Plaintext, keys — if keys never leave the client |
| Attacker with the user’s device | Everything on the device, including decrypted open notes | Notes on other devices (once locked), the master key if it is not persisted |

The threat model has limits, and the docs must say so: a keylogged or compromised device defeats client-side encryption; a malicious client build could exfiltrate keys; and “zero knowledge” holds only for the server, not for a hostile device.

Key Features

  • Client-side encryption with established primitives (WebCrypto AEAD such as AES-GCM; PBKDF2/Argon2 via an audited library)
  • Envelope encryption — per-note data keys wrapped by a derived master key
  • Untrusted server — stores ciphertext + wrapped keys + minimal metadata only
  • Separate authentication and encryption keys
  • Explicit recovery options (none, or an offline recovery key) with honest tradeoff copy
  • Encrypted titles with client-side indexing
  • Honest, in-product threat-model documentation

Functional Requirements

  • Derive a master key from the password + salt using an established KDF; never store the master key server-side.
  • Encrypt every note with a fresh data key using authenticated encryption; wrap the data key with the master key.
  • Transmit and store only ciphertext and wrapped keys; store no plaintext server-side.
  • Authenticate users server-side without the server ever receiving the encryption key.
  • Sync ciphertext between devices; handle ordering and conflicts at the ciphertext level.
  • Provide the chosen recovery path (none or recovery key) and clearly document the tradeoff.
  • Encrypt note titles (or make the decision to leak them an explicit, documented setting).
  • User Stories

    • As a privacy-minded note-taker, I want the server operator to be unable to read my notes even with full database access, so that my content is protected by architecture, not policy.
    • As a developer learning cryptography, I want the key derivation, encryption, and wrapping steps visible and testable, so that I can verify the design rather than trust a library’s black box.
    • As a careful user, I want the recovery tradeoff explained before I choose, so that I never lose my notes by surprise.

    MVP Scope

  • Register/login with a password; KDF-derived master key held only on the client.
  • Create/edit/list notes with per-note keys, encrypted titles, and server-side ciphertext storage.
  • Client-side unlock and search; logout clears the key material from memory.
  • Envelope encryption with a documented, tested crypto module.
  • In-product threat model and recovery explanation.
  • Multi-device sync, sharing with out-of-band keys, and a recovery-key flow are natural second-phase additions.

    Project Timeline

    • Phase 1 — Crypto core (Week 1): Choose the audited primitives; implement and test derivation + encryption + envelope wrapping as pure functions with known-answer vectors.
    • Phase 2 — Server (Week 2): Minimal ciphertext store and authentication that never touches keys.
    • Phase 3 — Client (Weeks 3–4): Note editing, client-side key handling, unlock/lock lifecycle.
    • Phase 4 — Sync (Week 5): Ciphertext sync and ordering; encrypted-title indexing.
    • Phase 5 — Harden + document (Week 6): Threat model doc, recovery tradeoff UI, and a design review pass by another developer.

    Testing Strategy

    • Known-answer tests — encryption/decryption round-trips against library test vectors, not just self-consistency.
    • Round-trip tests — decrypt(encrypt(x, key), key) === x across key and payload boundaries.
    • Key-separation tests — ciphertext produced under one key fails to decrypt under another; wrapped keys are useless without the master key.
    • Server-isolation tests — the server code path can never receive a plaintext note or key (assertable at the API boundary).
    • Memory tests — logout clears key material from client state.
    • Adversarial review — a second developer attacks the design (docs + code) before it is called done; findings documented.

    Security and Privacy Considerations

    • Established primitives only. Use WebCrypto’s authenticated encryption and a maintained KDF implementation — or an audited library such as libsodium. Never invent or hand-roll algorithms, and do not claim a design is secure merely because encryption is used.
    • Keys never leave the client. The master key lives only in the session; the server stores wrapped keys and can never unwrap them.
    • Key-loss reality. Losing the password loses the notes (or requires the user-held recovery key). This tradeoff is stated in the UI, not buried in docs.
    • Metadata leaks. Note count, timestamps, and sync activity are visible to the server; encrypted titles close the biggest content leak, and the residual metadata is documented.
    • Device compromise defeats everything. Client-side encryption protects against a hostile server, not a hostile device; the threat model says so.
    • Sharing caution. If sharing is added, it must use out-of-band key exchange (an encrypted payload plus a key sent by a separate channel) — the server never sees shared keys.
    • Not a vault. The README and UI discourage storing highly sensitive secrets in an unverified student project.

    Success Metrics

    • Crypto tests: round-trip and key-separation suites green; known-answer vectors pass.
    • Server isolation: code review confirms no plaintext/key path exists on the server.
    • A threat-model walkthrough: the developer can explain, for each attacker row, exactly what is and is not protected.
    • Honest framing: no “unbreakable” or “military-grade” language anywhere in the product.

    Common Challenges

    • Key management UX — the privacy-maximal choice (no recovery) is hostile to normal users; the recovery-key option shifts risk back to them; the tradeoff copy is the hard part.
    • Encrypted metadata — titles, tags, and search all fight against encryption; minimizing leakage while staying usable requires deliberate scope cuts.
    • Sync of ciphertext — reusing ordering/conflict logic is fine, but every client must treat server bytes as untrusted ciphertext, never as plaintext.
    • False confidence — encryption that is implemented but not reasoned about (or not audited) is marketing, not security; the honest threat model is what makes this project educational.
    • Algorithm temptation — inventing a “better” scheme is how real products fail; audited primitives and standard constructions are the entire point.

    Learning Objectives

    • Implement and test envelope encryption with established, audited primitives.
    • Explain the difference between authentication and encryption keys and why the separation matters.
    • Build a threat model and design to it, including metadata and recovery tradeoffs.
    • Reason about what “zero knowledge” can and cannot promise, and communicate that honestly.
    • Evaluate a cryptographic design with adversarial review instead of trust.

    Why This Idea Is Different

    This is the site’s confidentiality-architecture project, and it is explicitly differentiated from the offline-first note-taking app: that project answers “how do my notes survive flaky networks?”, this one answers “how do my notes stay secret from the server?” — and it is not simply another offline note app, since offline use is optional here and the defining feature is client-side encryption. It sits in the same privacy family as the data breach monitor, which watches for exposure after the fact, and the privacy-first web analytics dashboard, which refuses to collect what it does not need — both share the ethos that architecture, not policy, is what protects users.

    What Similar Tools Exist

    | Tool type | Approach | Limitation |
    |———–|———-|————|
    | Standard cloud notes | Server-side storage | Operator and breaches can read plaintext |
    | E2E-encrypted note products | Client-side encryption | Closed implementation; hard to learn from |
    | Crypto libraries | Primitives you assemble | No product, no key-management UX, easy to misuse |

    This project’s differentiators: a fully readable implementation, honest recovery/metadata/threat-model decisions, and a design that treats the server as untrusted by construction.

    Technology Stack

    • TypeScript — client and server share types (ciphertext envelope, note records)
    • WebCrypto (AES-GCM) + a maintained KDF implementation (or libsodium) — audited primitives only
    • React — the client UI
    • Node.js (or Python FastAPI) — the ciphertext store
    • PostgreSQL or SQLite — server-side storage of ciphertext, wrapped keys, and minimal metadata
    • Vitest/Jest — known-answer, round-trip, and key-separation tests

    Future Enhancements

    • Multi-device ciphertext sync with client-side conflict handling
    • Sharing via out-of-band key exchange (encrypted payload + separate-channel key)
    • Recovery-key flow with printable backup and explicit risk copy
    • Client-side full-text search over decrypted titles/bodies while locked
    • An independent security review pass by another developer before any “production” use

    Browse more Product Ideas · Advanced Ideas

    Technology

    databasejavascript
    ItsMyIdeas Editorial Team

    ItsMyIdeas Editorial Team

    Published on September 7, 2026

    A team of developers, researchers, and innovators who review and publish practical ideas for builders and creators.

    Editorial Note: This idea was reviewed and published by the ItsMyIdeas editorial team. All content is checked for originality, accuracy, and practical value before publication.
    Questions or suggestions? Contact us or submit your own idea.
    Share this idea: