Encrypted Note Password Confirmation
I'm creating a pastebin-style application which stores notes and has the following options:
- Ephemeral, where it is deleted as soon as it is read
- Encrypted, where the content is encrypted before being sent to the server (used to determine if a client should be prompted for a password)
- Expiration, a TTL
During the flow of the application, when you navigate to the endpoint: example.com/ABCD1234
, it first loads metadata about the note with ID ABCD1234. Even if the note is ephemeral, reading the metadata should not remove the note. Once any necessary parameters are provided, it will reddirect to example.com/ABCD1234/read
which pulls the content and removes it from the server if the note is ephemeral.
My trouble is from prompting the password. There are a few options that I can see.
Send the password as part of the request to retrieve the note and check if the password is correct on the server side. Personally, I would like to avoid the plaintext password ever being sent over the network or being seen by the server in any capacity, so this is ideally not going to be used.
When creating an encrypted note, the client would generate a hash of the password and send it along with the encrypted content to be stored on the server's backend datastore. When retrieving the metadata, provide the password hash back to the client so it can be easily checked in the browser to determine if the password is correct. Of course this option opens up the possibility of password brute forcing by cracking the hash, but a sufficiently complex password shouldn't be particularly vulnerable.
When creating an encrypted note, use a piece of randomly generated (on the client side) but known plaintext and, using the same password, some ciphertext as well of that known plaintext which is completely unrelated to the actual content e.g. "This is a challenge". Both the plaintext and ciphertext of this challenge would be provided via the metadata, and if the password entered can decrypt the ciphertext into the known plaintext "This is a challenge", then the redirect on the client side will occur.
Some kind of non-interactive zero knowledge proof, but this is currently difficult to implement.
Note that this is not about authorizing access to the content itself or I would integrate with some identity provider and have account-based reading. It's simply about providing an easier experience to the user so that if they type in the wrong password, it won't pull the content, delete the note, and decrypt the data to garbled nonsense thus preventing them from ever being able to re-enter the correct password. I just want the browser to confirm it knows the right password before deleting ephemeral notes.