\ We copy secrets into random websites way more often than we like to admit.
API keys. Recovery phrases. Draft contracts. Love letters. \n And every time, there’s that little voice in your head:
I got tired of that voice. So I built Encrypter, a tiny static site that lets you encrypt and decrypt text entirely in your browser, with no backend, no database, no login, and no tracking.
This post is the story behind it, how it works, and some of the trade-offs I made along the way.
I live in a world of:
When you google “encrypt text online”, you’ll find plenty of existing tools, and many of them are perfectly fine for a lot of people. They just make different trade-offs: some are integrated with accounts and cloud storage, some rely on a backend service, some focus on rich features and collaboration rather than being as small and transparent as possible.
I realized that my personal ideal looked a bit different:
So I turned this into a tiny side project: Encrypter.
The one-sentence version:
No servers touching your plaintext. No login. No account history.
The flow is intentionally minimal.
You get:
At no point does the plaintext leave your browser.
If the password and ciphertext match, you get your original text back. If not, you get an error and your secret stays secret.
There’s also a separate “Decrypt from QR code” route, which lets you upload a QR image containing ciphertext and then decrypt it with a password — again, all locally.
Encrypter runs as a static website:
From a threat-model perspective, that’s surprisingly powerful:
You can still attack the static files, of course. If someone tampers with the JavaScript, they could, in theory, exfiltrate plaintext or passwords. So the security story still includes:
But at least you’re not trusting a mysterious backend process that you can’t inspect at all.
There’s an important rule when building anything that touches security:
Encrypter uses the browser’s Web Crypto API under the hood, instead of rolling some “fun little cipher” in JavaScript.
A simplified version of the flow looks like this (pseudo-code):
// 1) Turn a password into a key using a KDF (e.g. PBKDF2) async function deriveKeyFromPassword(password, salt) { const enc = new TextEncoder(); const baseKey = await crypto.subtle.importKey( "raw", enc.encode(password), { name: "PBKDF2" }, false, ["deriveKey"] ); return crypto.subtle.deriveKey( { name: "PBKDF2", salt: salt, iterations: 100000, hash: "SHA-256", }, baseKey, { name: "AES-GCM", length: 256, }, false, ["encrypt", "decrypt"] ); } // 2) Encrypt a text string async function encryptText(plaintext, password) { const enc = new TextEncoder(); const data = enc.encode(plaintext); const salt = crypto.getRandomValues(new Uint8Array(16)); const iv = crypto.getRandomValues(new Uint8Array(12)); const key = await deriveKeyFromPassword(password, salt); const ciphertext = await crypto.subtle.encrypt( { name: "AES-GCM", iv: iv, }, key, data ); // Encode salt + iv + ciphertext into a single string (e.g. Base64) return encodeToString({ salt, iv, ciphertext }); }
On decrypt:
crypto.subtle.decrypt with AES-GCM.The password never leaves the browser. The plaintext never leaves the browser. Only the encoded salt + iv + ciphertext might be copied, shared, or turned into a link/QR.
One of my goals was: “make secrets easy to share without sharing secrets”.
That’s where links and QR codes come in.
The idea is simple:
https://encrypter.site/#/decrypt?c=ENCRYPTED_BLOB_HERE
c parameter from the URL.So the URL is useless without the password, but extremely convenient with it.
QR codes are just another way to carry the ciphertext (or the link that contains it).
This is handy in a few scenarios:
Again, the guarantee is: no server ever sees your plaintext. The server only ever needs to serve static JS, CSS, and HTML.
Important confession: \n Encrypter isnot trying to replace mature, audited tools like:
Those tools have much deeper security properties, community scrutiny, and feature sets.
Encrypter is intentionally:
If your threat model includes:
…you’ll still want the full power of mature cryptographic tools.
But if your threat model is closer to:
…then Encrypter sits in a nice spot between “do nothing” and “set up a full PGP workflow”.
A few things this side project reinforced for me:
The Web Crypto API is a bit verbose, but it’s:
Once you wrap it with a small utility layer, it’s perfectly usable for tools like this.
We love shipping “APIs for everything”, but for some categories, no backend is the best backend.
Static hosting + client-side logic means:
It doesn’t solve everything, but it’s a great baseline for this kind of tool.
If encryption feels heavy or confusing, people will:
A simple interface (“Encrypt”, “Decrypt”, password, done) lowers the friction enough that people might actually use it in everyday life.
No tool is magic, and Encrypter is no exception. A few honest disclaimers:
Encrypter started as “I just want something I can trust for my own secrets,” but now that it’s live, I’d genuinely love feedback from other developers, security folks, and anyone who cares about privacy.
If you try it and think:
—I want to hear it.
Suggestions on features, crypto defaults, copywriting, or even visual design are all welcome. My goal is not to build a giant platform, but to make a small, understandable, view-sourceable tool that people actually feel comfortable using.
If you’ve ever hesitated before pasting a secret into a random website, this tool is for you.
https://encrypter.site (or whatever URL you configure).Whether you adopt Encrypter, fork it, or roll your own, I hope this story nudges you to think a bit more carefully about where your secrets live — and who really needs to see them.
\


