From ec12e174cdca6bf0809fb7228e92b3228dbb2b25 Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 22 Aug 2020 12:13:36 -0700 Subject: [PATCH] Documentation updates (Thanks @guydebros!) (#1031) * updated README.md: - corrected information about encryption - made additions based on proposed changes to overview.md - made other changes for clarity and grammar * ongoing changes to overview.md * added note that `pycrypto` is required made other small changes for grammar and clarity * added new python decryption script to encryption.md * updated encryption.md to clarify dependencies other relatively small changes for clarity straightened quotes Co-authored-by: Guy B. deBros --- README.md | 68 ++++++++++++------------ docs/encryption.md | 127 ++++++++++++++++++++++++++++++++------------- docs/overview.md | 67 ++++++++++++++++-------- 3 files changed, 168 insertions(+), 94 deletions(-) diff --git a/README.md b/README.md index 2c266095..54b36b7d 100644 --- a/README.md +++ b/README.md @@ -4,68 +4,68 @@ jrnl [![Build Status](https://travis-ci.com/jrnl-org/jrnl.svg?branch=release)](h _To get help, [submit an issue](https://github.com/jrnl-org/jrnl/issues/new/choose) on Github._ -*jrnl* is a simple journal application for your command line. Journals are -stored as human readable plain text files - you can put them into a Dropbox -folder for instant syncing and you can be assured that your journal will still -be readable in 2050, when all your fancy iPad journal applications will long be -forgotten. +`jrnl` is a simple journal application for the command line. -Optionally, your journal can be encrypted using the [256-bit -AES](http://en.wikipedia.org/wiki/Advanced_Encryption_Standard). +Its goal is to facilitate the rapid creation and viewing of journal entries. It +is flexible enough to support different use cases and organization strategies. +It is powerful enough to search through thousands of entries and display, or +"filter," only the entries you want to see. -### Why keep a journal? +`jrnl` includes support for [128-bit AES +encryption](http://en.wikipedia.org/wiki/Advanced_Encryption_Standard) using +[cryptography.Fernet](https://cryptography.io/en/latest/fernet/). -Journals aren't just for people who have too much time on their summer -vacation. A journal helps you to keep track of the things you get done and how -you did them. Your imagination may be limitless, but your memory isn't. For -personal use, make it a good habit to write at least 20 words a day. Just to -reflect what made this day special, or why you haven't wasted it. For -professional use, consider a text-based journal to be the perfect complement to -your GTD todo list - a documentation of what and how you've done it. +## In a Nutshell -In a Nutshell -------------- +To make a new entry, just enter -To make a new entry, just type +``` sh +jrnl yesterday: Called in sick. Used the time to clean the house and write my +book. +``` - jrnl yesterday: Called in sick. Used the time cleaning the house and writing my book. - -and hit return. `yesterday:` will be interpreted as a timestamp. Everything -until the first sentence mark (`.?!`) will be interpreted as the title, the -rest as the body. In your journal file, the result will look like this: +`yesterday:` is interpreted by `jrnl` as a timestamp. Everything until the +first sentence ending (either `.`, `?`, or `!`) is interpreted as the title, and +the rest as the body. In your journal file, the result will look like this: [2012-03-29 09:00] Called in sick. - Used the time cleaning the house and writing my book. + Used the time to clean the house and write my book. -If you just call `jrnl`, you will be prompted to compose your entry - but you -can also configure _jrnl_ to use your external editor. +Entering `jrnl` without any arguments launches an external editor where you can +write your entry. `jrnl` will generate a time stamp for the entry after you save +and close the editor window. -For more information, please read our [documentation](https://jrnl.sh/overview/). +For more information, please read the +[documentation](https://jrnl.sh/overview/). ## Contributors ### Maintainers -Our maintainers help keep the lights on for the project. Please thank them if -you like jrnl. + +Our maintainers help keep the lights on for the project: + * Jonathan Wren ([wren](https://github.com/wren)) * Micah Ellison ([micahellison](https://github.com/micahellison)) +Please thank them if you like `jrnl`! + ### Code Contributors -This project is made with love by the many fabulous people who have -contributed. Jrnl couldn't exist without each and every one of you! + +This project is made with love by the many fabulous people who have contributed. +`jrnl` couldn't exist without each and every one of you! -If you'd also like to help make jrnl better, please see our [contributing +If you'd also like to help make `jrnl` better, please see our [contributing documentation](CONTRIBUTING.md). -### Financial Backers +## Financial Backers Another way show support is through direct financial contributions. These funds go to covering our costs, and are a quick way to show your appreciation for -jrnl. +`jrnl`. [Become a financial contributor](https://opencollective.com/jrnl/contribute) and help us sustain our community. diff --git a/docs/encryption.md b/docs/encryption.md index 806064b3..a4f0a35a 100644 --- a/docs/encryption.md +++ b/docs/encryption.md @@ -1,60 +1,113 @@ # Encryption -## Encrypting and decrypting +## A Note on Security -If you don’t choose to encrypt your file when you run -`jrnl` for the first time, you can encrypt -your existing journal file or change its password using this: +While `jrnl` follows best practices, total security is never possible in the +real world. There are a number of ways that people can at least partially +compromise your `jrnl` data. See the [Privacy and Security](./security.md) page +for more information. + +## Dependencies + +As of version 2.0, `jrnl`'s encryption functions require +[`cryptography`](https://pypi.org/project/cryptography/), which is available in +the Python Package Index (PyPI) and can be installed using `pip`: ``` sh -jrnl --encrypt +pip3 install cryptography ``` -If it is already encrypted, you will first be asked for the current -password. You can then enter a new password and your plain journal will -replaced by the encrypted file. Conversely, +Previous versions of `jrnl` require +[`pycrypto`](https://pypi.org/project/pycrypto/): + +```sh +pip3 install pycrypto +``` + +## Encrypting and Decrypting + +Existing plain text journal files can be encrypted using the `--encrypt` +command: ``` sh -jrnl --decrypt +jrnl --encrypt [FILENAME] ``` -will replace your encrypted journal file with a journal in plain text. You -can also specify a filename, i.e. `jrnl --decrypt plain_text_copy.txt`, -to leave your original file untouched. +You can then enter a new password, and the unencrypted file will replaced with +the new encrypted file. -## Storing passwords in your keychain +This command also works to change the password for a journal file that is +already encrypted. `jrnl` will prompt you for the current password and then new +password. -Whenever you encrypt your journal, you are asked whether you want to -store the encryption password in your keychain. If you do this, you -won’t have to enter your password every time you want to write or read -your journal. +Conversely, -If you don’t initially store the password in the keychain but decide to -do so at a later point – or maybe want to store it on one computer but -not on another – you can run `jrnl --encrypt` on an encrypted -journal and use the same password again. +``` sh +jrnl --decrypt [FILENAME] +``` -## A note on security +replaces the encrypted journal file with a plain text file. You can also specify +a filename, e.g., `jrnl --decrypt plain_text_copy.txt`, to leave the original +encrypted file untouched and create a new plain text file next to it. -While `jrnl` follows best practices, total security is an illusion. -There are a number of ways that people can at least partially -compromise your `jrnl` data. See the [Privacy and Security](./security.md) -documentation for more information. - -## No password recovery +## Storing Passwords in Your Keychain There is no method to recover or reset your `jrnl` password. If you lose it, -your data is inaccessible. +your data will be inaccessible forever. -## Manual decryption +For this reason, when encrypting a journal, `jrnl` asks whether you would like +to store the password in your system's keychain. An added benefit is that you +will not need to enter the password when interacting with the journal file. -Should you ever want to decrypt your journal manually, you can do so -with any program that supports the AES algorithm in CBC. The key used -for encryption is the SHA-256-hash of your password, the IV -(initialisation vector) is stored in the first 16 bytes of the encrypted -file. The plain text is encoded in UTF-8 and padded according to PKCS\#7 -before being encrypted. Here’s a Python script that you can use to -decrypt your journal: +If you don't initially store the password in your keychain but decide to do so +later---or if you want to store it in one computer's keychain but not in another +computer's---you can run `jrnl --encrypt` on an encrypted journal and use the +same password again. This will trigger the keychain storage prompt. + +## Manual Decryption + +Should you ever want to decrypt your journal manually, you can do so with any +program that supports the AES algorithm in CBC. The key used for encryption is +the SHA-256 hash of your password. The IV (initialization vector) is stored in +the first 16 bytes of the encrypted file. The plain text is encoded in UTF-8 and +padded according to PKCS\#7 before being encrypted. + +Here is a Python script that you can use to decrypt your journal: + +``` python +#!/usr/bin/env python3 + +import base64 +import getpass +from pathlib import Path +from cryptography.fernet import Fernet +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives import hashes +from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC + + +filepath = input("journal file path: ") +password = getpass.getpass("Password: ") + +with open(Path(filepath),"rb") as f: + ciphertext = f.read() + +password = password.encode("utf-8") +kdf = PBKDF2HMAC( + algorithm=hashes.SHA256(), + length=32, + salt=b"\xf2\xd5q\x0e\xc1\x8d.\xde\xdc\x8e6t\x89\x04\xce\xf8", + iterations=100_000, + backend=default_backend(), +) + +key = base64.urlsafe_b64encode(kdf.derive(password)) + +print(Fernet(key).decrypt(ciphertext).decode('utf-8')) +``` + +If you're still using `jrnl` version 1.X, the following script serves the same +purpose: ``` python #!/usr/bin/env python3 diff --git a/docs/overview.md b/docs/overview.md index 67feedcf..6f977ce7 100644 --- a/docs/overview.md +++ b/docs/overview.md @@ -1,41 +1,62 @@ # Overview -## Features +`jrnl` is a simple journal application for the command line. -### Command-Line Interface +`jrnl`'s goal is to facilitate the rapid creation and viewing of journal +entries. It is flexible enough to support different use cases and organization +strategies. It is powerful enough to search through thousands of entries and +display, or "filter," only the entries you want to see. -`jrnl` is a simple but powerful plain text journal application for the command -line. Everything happens on the command line. +`jrnl` has most of the features you need, and few of the ones you don't. -### Text-Based +## Plain Text -`jrnl` stores your journals as human-readable, future-proof plain text files. -You can store them wherever you want, including in shared folders to keep them -synchronized between devices. And because journal files are stored as plain -text, you can rest assured that your journals will be readable for centuries. +`jrnl` stores each journal in plain text. `jrnl` files can be stored anywhere, +including in shared folders to keep them synchronized between devices. Journal +files are compact (thousands of entries take up less than 1 MiB) and can be read +by almost any electronic device, now and for the foreseeable future. -### Support for Multiple Journals +## Tags + +To make it easier to find entries later, `jrnl` includes support for inline tags +(the default tag symbol is `@`). Entries can be found and filtered + +## Support for Multiple Journals -`jrnl` allows you to work with multiple journals, each of which is stored as a -single file using date and time tags to identify individual entries. `jrnl` -makes it easy to find the entries you want, and only the ones you want, so that +`jrnl` includes support for the creation and management of multiple journals, +each of which can be stored as a single file or as a set of files. Entries are +automatically timestamped in a human-readable format that makes it easy to view +multiple entries at a time. `jrnl` can easily find the entries you want so that you can read them or edit them. -### Support for External Editors +## Support for External Editors -`jrnl` allows you to search for specific entries and edit them in your favorite -text editor. +`jrnl` plays nicely with your favorite text editor. You may prefer to write +journal entries in an editor. Or you may want to make changes that require a +more comprehensive application. `jrnl` can filter specific entries and pass them +to the external editor of your choice. -### Encryption +## Encryption -`jrnl` includes support for [256-bit AES +`jrnl` includes support for [128-bit AES encryption](http://en.wikipedia.org/wiki/Advanced_Encryption_Standard) using -[cryptography.io](https://cryptography.io). +[cryptography.Fernet](https://cryptography.io/en/latest/fernet/). The +[encryption page](./encryption.md) explains `jrnl`'s cryptographic framework in +more detail. -### Multi-Platform Support +## Import and Export -`jrnl` is compatible with most operating systems. Pre-compiled binaries are available through several distribution channels, and you can build from source. See the installation page for more information. +`jrnl` makes it easy to import entries from other sources. Existing entries can +be [exported](./export.md) in a variety of formats. -### Open-Source +## Multi-Platform Support -`jrnl` is written in [Python](https://www.python.org) and maintained by a [friendly community](https://github.com/jrnl-org/jrnl) of open-source software enthusiasts. +`jrnl` is compatible with most operating systems. Pre-compiled binaries are +available through several distribution channels, and you can build from source. +See the [installation page](./installation.md) for more information. + +## Open-Source + +`jrnl` is written in [Python](https://www.python.org) and maintained by a +[friendly community](https://github.com/jrnl-org/jrnl) of open-source software +enthusiasts.