Ever since reading a HN post on keeping a journal, I have been an avid journaler. I have tried out various methods of recording my thoughts throughout the day, starting with paper and quickly migrating to technology for searchability and security.
I was drawn to jrnl.sh due to the simplicity of a cli and its promise of “military-grade encryption” (I now understand that this is just a marketing term for AES).
Years have passed and since them I have learned a lot, especially in the field of cryptography.
After taking a look at the jrnl source code, I found some scary things:
def make_key(self, password): """Creates an encryption key from the default password or prompts for a new password.""" self.key = hashlib.sha256(password.encode("utf-8")).digest()
The user’s password is weakly hashed with sha256.
Scenario: Loading an encrypted journal with password in config Given we use the config "encrypted_with_pw.json" When we run "jrnl -n 1" Then the output should contain "2013-06-10 15:40 Life is good"
It was a very unpleasant suprise when I found my password in plaintext in my config file. Apparently it’s a feature, not a bug.
Jrnl’s cryptography is great for keeping out nosy roommates, but it’s clearly inadequate for a crypto nut like myself.
I decided that I would build my own command line journaling application, naming it Jay.
Jay was built with the following goals in mind:
- Simple. It’s a journal and nothing more.
- Quick. It’s asymetrically encrypted, meaning that you need a password when reading your notes, but not when you jot them down.
- Private. Your notes are kept locked away behind your (hopefully secure) password.
- Secure. Jay follows up-to-date security recommendations, using pbkdf2 and rsa 4096.
I chose to write Jay in Go because the language’s standard library has plenty of support for crypto and because I found it’s terseness optimal for handling extremely sensitive data (i.e. journal entries).
The source code for Jay can be found at aaronduino/jay