fugacious
fugacious copied to clipboard
Encrypt messages inside database
Just a thought. You could encrypt messages inside the database, each with its own random key. The encryption key could become part of the URL; the server would throw it out. This would secure people's messages against someone hacking into the database and downloading it (hello Patreon!). Although the combination of the database and the web server logs could still be used to decrypt things (since the key is in the url), so the logs would need to be deleted or anonymized promptly to get full protection out of this.
Creation of a message:
- Generate 64 random chars, not 32.
- First 32 chars become the database primary key, as now.
- Second 32 chars are used to encrypt the message
- The url is https://server/m/(64 chars)
Accessing a message:
- Split the incoming "key" in half, use the first half to look up the db row. Use the second half to decrypt it.
What if someone modifies part of the encryption key? Then the web page would display gibberish?
- You could add a column to the db that's e.g. SHA512(real encryption key) and make sure the incoming one matches. If it doesn't match, return HTTP 404.
One idea that crossed my mind is to use the WebCrypto APIs before sending the message to the server. As @tgs suggests, you could generate a 32 character primary key, and a 32 character key for encrypting the message, but instead of having the URL be:
https://server/m/(64 chars)
as @tgs suggests, it could be:
https://server/m/primary_key#encryption_key
The portion of the URL after the hash doesn't get sent to the server, but it's available to javascript in the browser. The process could be:
- User types in data and hits submit.
- Browser generates a random key and encrypts the message.
- Browser submits encrypted message to the server.
- Server stores the message and returns the primary key.
- Browser generates a URL based on the encryption key it generated and the primary key the server generated.
When a user clicks the URL
- Browser retrieves the data in the primary key from the server
- Browser extracts the encryption key from the URL
- Browser decrypts the message and displays it to the user
As a result, the server never has possession of the plaintext message or the keys to decrypt the ciphertext, but the workflow for the user is still as simple as copying and pasting a URL.