193 lines
8.6 KiB
Markdown
193 lines
8.6 KiB
Markdown
# Dethnote
|
|
|
|
**WORK IN PROGRESS**
|
|
|
|
This is a Go web app that lets you store a securely encrypted note that may be
|
|
unlocked in the event of an emergency or untimely tragedy.
|
|
|
|
Basically you write a note and leave your e-mail address, and the note is
|
|
encrypted using AES-256 with a very strong, randomly generated Diceware pass
|
|
phrase. The server does not store your e-mail address or pass phrase anywhere
|
|
in a recoverable form.
|
|
|
|
An example use case:
|
|
|
|
> I want to make sure that, in case of an unexpected tragedy, that my family
|
|
> is able to access my Password Manager vault to log into my accounts.
|
|
>
|
|
> So I go and create a secure note on Dethnote. Enter my email address and
|
|
> write my note.
|
|
>
|
|
> The server generates a strong, random Diceware passphrase and encrypts my
|
|
> note with it and tells me what the passphrase is.
|
|
>
|
|
> I write it down on a piece of paper that I put in my wallet: "In case of
|
|
> emergency, visit <dethnote url> and enter this password:"
|
|
>
|
|
> If something happens and somebody finds the paper and enters the password,
|
|
> I get an e-mail notifying me that the password has been used and that I
|
|
> have 72 hours to respond. If I don't answer, I am presumed dead and the
|
|
> secure note will be decrypted.
|
|
>
|
|
> If I got mugged and my wallet was stolen, no big deal: I can just go and
|
|
> re-encrypt with a new password at my earliest convenience. Even if the
|
|
> criminal tried to decrypt my note, I have 72 hours to prevent it from
|
|
> being unlocked.
|
|
|
|
# Usage
|
|
|
|
## Creating a Message
|
|
|
|
As the end user who wants to create an encrypted note:
|
|
|
|
1. Go to the web app homepage and scroll down to create a new note.
|
|
* Provide your email address so we can verify you control the account. This is
|
|
because, when your note is being decrypted, we will send you a confirmation
|
|
e-mail with actions you may take. If you don't respond to the e-mail in
|
|
time, your message will be decrypted, so it's important that we have a
|
|
verified e-mail address to go with your message.
|
|
* Choose how long of a password you want to have generated for you. Six words
|
|
or more are good, but I recommend eight.
|
|
* Choose what "timeout window" you want to be enforced when somebody tries
|
|
to decrypt your note. The default is 72 hours. This means if your password
|
|
is entered, you will get a notification e-mail and have 72 hours to respond
|
|
to it, before your message will be decrypted.
|
|
* Finally, write the message that you want to protect.
|
|
2. Submit the message. This will encrypt it with a random password and send you
|
|
a confirmation e-mail with details.
|
|
* The confirmation page tells you what the password is. You can not log in
|
|
with the password yet, though, until you verify the email address.
|
|
* A random "verify token" is created along with your message. When you click
|
|
the verification link in your e-mail, all that happens is the app puts that
|
|
verify token on your browser's session.
|
|
* When you enter your password after clicking the verify link, your email
|
|
address will be confirmed and you will be given options what to do next.
|
|
* You can re-encrypt with a new random password.
|
|
* You can delete the message.
|
|
* You can replace the message with a new one.
|
|
|
|
Now you may log out. The next time your password is entered, the program will
|
|
enter the Decryption Routine.
|
|
|
|
## Decryption Routine
|
|
|
|
After your email is verified, if somebody (or you) goes to open the message up
|
|
by providing the password, the app will enter the Decryption Routine on that
|
|
message.
|
|
|
|
1. The user who wants to decrypt the message must also provide their email address.
|
|
* This is to verify that the e-mail configuration is working as normal. If
|
|
the server can't send out an e-mail, then it can't notify the owner of
|
|
the secure note that the Decryption Routine has begun!
|
|
2. The requester clicks on a link in their e-mail to verify their e-mail address.
|
|
3. The owner of the note is sent an e-mail to notify them that the Decryption
|
|
Routine has started. The owner has 72 hours (default) to respond to the
|
|
e-mail. The email itself contains immediate actionable links:
|
|
* You can cancel the request. This keeps the password the same but cancels
|
|
the Decryption Routine.
|
|
* You can delete the message completely, preventing it from being opened.
|
|
* You can immediately authorize it to be opened now.
|
|
4. When the timeout window expires or the owner of the note authorizes the
|
|
access, the request is e-mailed to notify them that the note is now able
|
|
to be decrypted.
|
|
5. The requester goes back to the web app and enters the password. This time
|
|
they are allowed to access the note.
|
|
|
|
After a note is decrypted, the user viewing it may take actions on it:
|
|
|
|
* Do nothing and close their browser session. The next time the password is used,
|
|
immediate access is granted to the note.
|
|
* Lock the note back down. This will cause the Decryption Routine to run again the
|
|
next time the password is used.
|
|
* Delete the note.
|
|
* Re-encrypt it with a new random password.
|
|
* Replace the note with a new version while keeping the same password.
|
|
|
|
# Security Notes
|
|
|
|
## Diceware Passwords
|
|
|
|
* The randomly generated passwords are never stored anywhere in a
|
|
recoverable fashion.
|
|
* The password is hashed with bcrypt with a slow iteration count that will
|
|
resist brute force attacks. The Diceware passwords themselves are also
|
|
long enough to resist brute forcing just in general.
|
|
* The hash of the bcrypt password is used as the identifier on disk where
|
|
the data is stored.
|
|
|
|
## Encryption
|
|
|
|
Literally everything about the note is encrypted.
|
|
|
|
The bcrypt+SHA256 hash serves as the key for AES-128 in CBC mode which is
|
|
used to encrypt the contents of the data files.
|
|
|
|
On disk there are two files stored with every note:
|
|
|
|
* `meta.bin` is an AES-256 encrypted JSON document that stores the metadata
|
|
about the note: the owner's email address, verified email status, the
|
|
bcrypt hash of the Diceware password, etc.
|
|
* `message.bin` is an AES-256 encrypted plain text document that stores the
|
|
actual body of the message you have written.
|
|
|
|
When the web app is dealing with the encrypted note after it received the
|
|
password (or generated the new one for new notes), it only deals with
|
|
`meta.bin` while it's trying to validate email addresses and run through
|
|
the Decryption Routine. This way the plain text of your message is rarely
|
|
ever in the application's working memory.
|
|
|
|
Only when access has been fully granted to decrypt the message will the
|
|
`message.bin` file be opened.
|
|
|
|
## Zero Admin Visibility
|
|
|
|
The admin of the web server has zero visibility into any of the data in
|
|
the service.
|
|
|
|
* The filesystem is just full of hexadecimal path names leading to
|
|
files encrypted with AES-256.
|
|
* No e-mail addresses are visible to the admin, because those are stored
|
|
_inside_ those encrypted files.
|
|
* The admin can't snoop on other peoples messages because they are _very_
|
|
heavily encrypted:
|
|
* Strong Diceware pass phrases that would resist brute force attacks
|
|
for millions of years even with a fast hashing algorithm.
|
|
* Dethnote uses the bcrypt hashing algorithm with a slow iteration
|
|
count making brute forcing all the harder.
|
|
* The admin can't enumerate what passwords _even exist_. All he can see
|
|
is the hexadecimal data paths, but doesn't know what the passwords are,
|
|
and can't even tell _whose_ files belong to _who_. And brute forcing
|
|
random Diceware passwords is practically impossible.
|
|
|
|
## Robustness and "Offline Mode"
|
|
|
|
This service relies heavily on a reliable e-mail server for sending out
|
|
verification e-mails, Decryption Routine warning e-mails, and so-on.
|
|
|
|
But this is the real world and web servers aren't always reliable.
|
|
|
|
On the web, the service will naturally self-test the e-mail system:
|
|
before you can decrypt a note, you have to verify an e-mail address.
|
|
This ensures that the e-mail system is working, so that when the
|
|
Decryption Routine begins, it will be able to send an e-mail to the
|
|
note owner.
|
|
|
|
But I mainly wrote this service for myself, and so it has an "Offline
|
|
Mode" that works in absence of a running web server or e-mail configuration.
|
|
|
|
My web server backs up to my desktop PC at home, and so there will always
|
|
be a copy of _this application_ and its database of encrypted notes there.
|
|
The command line interface of the program allows you to immediately decrypt
|
|
and open a note _that you have a password for_. Example:
|
|
|
|
```bash
|
|
# Open a note with this password:
|
|
% dethnote -open "viewable require broom taunt spoiled"
|
|
Here is the contents of the note!
|
|
```
|
|
|
|
Note that this doesn't change any of the security considerations of the
|
|
service. The passwords are still just as hard to brute force. All this
|
|
"offline mode" does is bypass the need for e-mail validation and
|
|
minimum timeouts before opening notes.
|