Private data on public internet

November 6, 2025

639 words


On 15th December 2024 I did that dumb mental math you sometimes do and realized that in the next seven months I’ll be 21. I decided I would journal daily for 200 days until my birthday. Writing every day by hand is too much, and I can’t access handwritten pages everywhere. Obviously I didn’t want my journals to be publicly available, but I also didn’t want to make an account on some website and log in every day, and then log in again whenever I wanted to read them. If I ever wanted to read them on any non-personal device then I would not like to log in.

Now our task was to create a system that allows me to store everything publicly on my own website, but only I should be able to read it. I came up with the concept of key, inspired by JWT. The key can be any string. The key unlocks the journal. The key is not stored anywhere in code, in the database, or in the browser. It only exists in my mind. If I know it, the page becomes readable. If I don’t, it’s just noise. So I made an encrypted blog.

I wrote a script that takes a secret key and performs some mathematical operations on the text with that key. These operations are reversible, so it can be decrypted later. It’s not formally proven or industrial-grade encryption, but it’s good enough that no normal person or LLM can simply guess the logic. The entire thing is just two parts: the encryption script and the blog system. The encryption script lives locally on my computer. It takes the journal entry and the key and encrypts the text so it is only recoverable with that same key. I run it, it gives out an encrypted blob, and that blob is what gets stored. The encrypted text is then stored wherever I want whether database, files, doesn’t matter. The journal website has a built-in decryptor that takes two things: the encrypted text and the key the user types in. Neither side stores the key anywhere. It only exists in memory for the moment you type it.

Under the hood it’s just some reversible bit manipulation. A simplified version of the encryptor looks like this:

import base64

def encrypt(text, key):
    r = text[::-1]
    b = bytearray(ord(c) ^ ord(key[i % len(key)]) for i, c in enumerate(r))
    return base64.b64encode(b).decode()

The frontend just reverses that. Something tiny like:

function onKeyChange(key) {
  const plain = Decryptor(encryptedText, key)
  setDisplayed(plain || encryptedText)
}

I wanted something better than the usual password wall. So I made it real-time. Every keystroke runs the decryptor. Type the wrong key and it's just noise. But as you complete the correct key, letter by letter, the text becomes more and more readable. There's no loading screen, no button press. One moment it's noise, and the next moment it all makes sense.

watch the text become readable as you type the correct key

The whole point of this was simple: how can I store my private data so I can access it from any device with internet, without giving that data to anyone else. Even if the database leaks, all anyone sees is encrypted blobs. The only thing that can unlock them is the key. If the key is lost, the data is gone forever. There is no recovery from it. It follows a zero-trust model. With this system working, I did complete all 200 days of journalling. It wasn’t as life changing as people claim online, but I tried, and I have a record of that time. Now I can read it anywhere as long as I remember the key. If one day I decide I’m done with that version of me, I don’t even need to delete anything. I can just forget the key.

You can try it yourself: https://sgaud.com/journal

Brainmade Logo