Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Encrypting notes (org-crypt) #43

Open
trmendes opened this issue Mar 15, 2017 · 44 comments
Open

Encrypting notes (org-crypt) #43

trmendes opened this issue Mar 15, 2017 · 44 comments

Comments

@trmendes
Copy link

It would be nice to be able to apply cryptography to my notes. Maybe using OpenKeyChain.

@ghost
Copy link

ghost commented Mar 21, 2017

+1

I think openkeychain crypto is async, though, which causes things to get complicated.

I have implemented something similar for Simplenote on android that is still pending PR. I used Spongycastle and symmetric password crypto.

However, for orgzly, I would prefer to edit something.org.gpg via openkeychain, and commit that to git and edit it in other synced environments, like *nix emacs, where epa could be used with the same credentials.

@ghost
Copy link

ghost commented Mar 23, 2017

Ah! You mean org-crypt! I was thinking full-note encryption, but that wouldn't actually be necessary, I guess.

Yes, +1 to being able to apply org-crypt-style crypto.

@mkaito
Copy link

mkaito commented Mar 28, 2017

I would absolutely love support for org-crypt via OpenKeyChain!

@avently
Copy link

avently commented Apr 28, 2017

You want to encrypt just one note?
I think we need an option to encrypt all notes before syncing with sources like Dropbox. Like Laverna did. Is that possible and easy for Orgzly?

@mkaito
Copy link

mkaito commented Apr 28, 2017

I think I would love to see both.

@timoc
Copy link

timoc commented Apr 30, 2017

I keep my org notes in an encrypted encfs folder, i would prefer to see orgzly more encfs aware, having some boxcryptor classic link or incorporate some cryptonite

@djmaze
Copy link

djmaze commented May 16, 2017

As a side note. Have you guys considered using Syncthing as opposed to some centralized cloud storage? It's end-to-end encrypted so additional encryption is not compulsory. Works quite well for me with Orgzly. If your devices are often running at different times, you'll want to run you own central server though.

@mkaito
Copy link

mkaito commented May 16, 2017 via email

@ghost
Copy link

ghost commented May 16, 2017

@djmaze

Yes. I use it.

However, there are some things in my notes that need even better security. I want org-crypt for those things.

There is no such thing as too much security. ;)

@robb-romans
Copy link

+1

@nevenz nevenz changed the title Cryptography Encrypting notes (org-crypt) Oct 29, 2017
@hyiltiz
Copy link

hyiltiz commented Feb 9, 2018

For now, we could use AES encryption like jrnl did. It is symmetric, simple and secure. http://jrnl.sh/encryption.html

@ghost
Copy link

ghost commented Apr 8, 2018

I prefer to use something that integrates out-of-the-box with actual org-mode in emacs, and gpg does that perfectly. If you have a file, say, notes.org.gpg, or if you use org-crypt to encrypt part of an org file, it works painlessly in emacs. I would want this to work just as painlessly (and in fact exactly the same since I use my file in both emacs and orgzly).

@ghost ghost mentioned this issue Apr 8, 2018
@psidhu
Copy link

psidhu commented Jul 10, 2018

An easy way to solve this (maybe) is to get keybase (kbfs) integration going. #252 is an open ticket regarding this. I think they give a 250GB allowance for free accounts.

I suppose you can have both kbfs and org-crypt if extra security is required, however.

@hyiltiz
Copy link

hyiltiz commented Jul 11, 2018

@Matt812's suggestion seems the most sensible one, and wouldn't be too hard to implement, I hope. When a user tries to open a .org.gpg file, orgzly can try to send a decryption intent for OpenKeychain, and prompt to install it to enable GPG support if it is not already installed. OpenKeychain already talks to a few apps of various kinds (K9 mail client, Android Password Store, Conversation instant messenger etc.), so it should be possible to talk to it through some internal API transparently, without the user having to copy-paste back and forth between the two apps.

@ghost
Copy link

ghost commented Jul 11, 2018

@hyiltiz

when the user tries to open a ".org.pgp" file

It that actually #202 ?

I'm not sure if these two issues are identical or not.

Maybe this issue is more about internal "org-crypt", like a section or bullet, and 202 is about whole-file encryption?

In both cases, I agree with you agreeing with me. ;)

@hyiltiz
Copy link

hyiltiz commented Jul 17, 2018

EDITED: Symmetric (AES) doesn't even need to export and load a secret key. Just passwords are required.
EDITED 2: performance
EDITED 3: libraries that provide AES

Yes, it was actually #202.

I think we should agree on the following: encryption is not an optional feature; it is an essential must-have feature for a personal note-taking software. With that in mind, any route that leads to (good/valid/solid) encryption should suffice, since something is better than nothing. We can then add other alternatives if necessary later. I propose we postpone implementing org-crypt in favor of something simpler yet secure. We can use asymmetric or symmetric keys.

While org-crypt compatible encryption support would be awesome, what I find myself doing is keep all my notes that I cannot use unencrypted in just a few notebooks (in Emacs). This syncs to my phone via Syncthing. Now, with Open Keychain, I can decrypt that .org.gpg file (after importing the key etc., but that is beyond the scope of Orgzly if we start with this). My next option is to copy that decrypted file into clipboard then to Orgzly but that is not a good practice in any way.

Asymmetric keys

It could work like this: if Orgzly could interface with Open Keychain s.t. once a .gpg is clicked, either the user is prompted to setup Open Keychain if not set up yet or the notebook file is "automatically" decrypted. This automatic process might work like this: Orgzly would open the file with OpenKeychain, which in turn requires password to unlock the private gpg key, then decrypt the file. Orgzly then accepts the decrypted file and stores it in memory where no other userspace processes (other apps except the OS itself) can access it. After making edits or viewing, Orgzly provides a lock button for the notebook, and notifies the user after 10 min to lock the notebook. When the user presses the lock button, Orgzly sends the decrypted notebook from the private memory to OpenKeychain to decrypt again and store to Orgzly's internal store (so the update will be picked up by a sync later on).

This above process seems to me the most fluent UX possible. org-crypt might work in a similar way, but as it is not file-based, I assume it might be a bit more complicated than the above proposal.

Symmetric key

Alternatively, a symmetric key based encryption should also suffice. While this can be done through Open Keychain in the same way as above, I believe there are libraries for Android that can manage AES (like this [1]). Therefore, this should be a quick, straightforward and secure implementation.

The UX will be similar, and might even be simpler. Upon creating a notebook from within Orgzly, the user can enable encryption in the option for a notebook. Upon clicking Enable Encryption, the user is asked for a password ~~for the AES key to be created and stored in Orgzly's private folder in the internal store.~~for the AES encryption. The library/software providing AES support deals with key generation and storage. From then on, whenever the notebook is clicked (to view or edit), it will be decrypted using that AES key storedthe same password, and will be encrypted at other times. To enable users to decrypt the notebook at other places, it should be possible to export the AES keythe user is simply required to remember the password (we might notify the user with small print text that they need to remember this password). Whether a new AES keypassword should be created for each notebook remains a design decision, based on a threat model, but I think for better UX, a single AES keypassword to be used by Orgzly for all the notes should suffice.

I tested this setup (details in the next comment), and it works. As of API 26+ (Android 8.0), AES is supported natively [2]. If platforms lower than this is targeted, then 3rd-party libraries are available [3] (though relying on 3rd party implementation has its own security risks).

I am not familiar with Android development, but it would be really awesome if someone could submit a Pull Request with this implemented.

Performance

As a bonus, quite a few devices now have hardware acceleration for AES, so it should be very fast even for large files, or for a lot of encryption/decryption cycles, and battery friendly.

Summary

  • Encryption is not an optional feature.
  • AES based symmetric encryption should be most straightforward to implement.
  • To implement asymmetric encryption, integrating with Open Keychain should be supported, for security and to not reinvent the wheel.
  • As a bonus, integration with Open Keychain can deal with symmetric encryption as well.
  • A note-based (or anything smaller than single .org file) might be implemented similarly but only in more complex ways.

@nevenz and everyone else, any thoughts/preferences? Once we have encryption, we may as well bump the version to v2.0. 🙌

[1] https://stackoverflow.com/questions/6788018/android-encryption-decryption-with-aes
[2] https://developer.android.com/reference/javax/crypto/Cipher
[3] https://github.com/scottyab/AESCrypt-Android

@ghost
Copy link

ghost commented Jul 17, 2018

@hyiltiz

Nicely written comment.

I completely agree on encryption is not an optional feature; it is an essential must-have feature for a personal note-taking software. (In fact, I had this discussion with the SimpleNote folks, who just told me that that was not the direction they were taking their product. /rolls eyes . That's why I gave up on that product -- plus I can't live without org mode.)

Correct me if I'm wrong, but the AES encryption option doesn't easily integrate with Emacs, right?

The benefit of having a file that ends with .org.gpg (especially if it is asymmetrically encrypted, but not necessarily) is that I can just open it with Emacs, and it works (via epa).

How would the AES-encrypted file be opened (easily) in emacs?

(For the record, my preference is openkeychain integration for whole-file encryption with an org.gpg extension so that I can just sync it with dropbox and use it in Emacs on any machine.)

@hyiltiz
Copy link

hyiltiz commented Jul 17, 2018

You can import your AES key to GPG (and use --cipher-algo AES256 flag when necessary), and simply provide your password for the AES encryption, and get EasyPG take care of the rest. I just tested this. Here are the steps:

  1. With GnuPG2 from within terminal, encrypt file gpg -c mynote.org (uses AES256 by defualt), but since default can be changed by user, we can specify --cipher-algo AES256). This asks for a password (which can be cached by keyring software); set it to test.
  2. [Optional] Decrypt with gpg -d mynote.org.gpg and provide password if asked (it should be cached so no password is required in systems that support this; macOS, Android, iOS and GNU/Linux supports password caching).
  3. Now open mynote.org.gpg from within emacs. The cached password is automatically used by Emacs (its wrappers, I assume), and simply the file content is opened in a Emacs buffer.
  4. Sync the mynote.org.gpg (via Syncthing or manually via email etc.) to Android. Now open it with Open Keychain and provide the password test. Open Keychain successfully decrypts.

In the end, the user always needs to remember a password regardless of whether symmetric or asymmetric encryption is used.

@fullstopslash
Copy link

fullstopslash commented Jul 18, 2018 via email

@ghost
Copy link

ghost commented Jul 18, 2018

@fullstopslash
I agree. That is basically one of the solutions @hyiltiz proposed.

And, yes, it works. I had it hooked up to a hacked SimpleNote app at one point.

The only issue is that it is asynchronous. You ask it to decrypt something for you, and it "gets back to you later" (calls back). Sometimes that really messes things up. This is because it might need to prompt the user for a password, which is completely async.

I'm confident we can crack this egg. Just takes a lot of sweat.

@Ypot
Copy link

Ypot commented Aug 2, 2018

How would this affect to the widget?

Just heads could be seen, and body need to be unencrypted?

User configurable what widget keeps visible?

No widget for encrypted notes?

@hyiltiz
Copy link

hyiltiz commented Aug 2, 2018

What I outlined above works very well with "no widget" or "widget includes heads and body".

@Ypot
Copy link

Ypot commented Aug 3, 2018

If heads can be seen and widget filters work, it's fair enough, I think.

@hyiltiz
Copy link

hyiltiz commented Oct 3, 2018

I would like to bring this to the attention of some of the key developers @nevenz @pxsalehi @tulth @MackieLoeffel @IvanMalison. So what is the status of this, in other words, where is this feature in your priority list, and if you would consider accepting a pull request for this feature, which of the alternatives proposed above would you consider most (and why)?

With some feedback and direction from you, the community may be able to come up with a pull request. To enhance user interface, we could even hide this encryption feature inside "Advanced", so only users who know they want it can enable it.

@nevenz
Copy link
Member

nevenz commented Oct 4, 2018

It's not high on my priority list, but PRs are welcome.

I don't have experience with OpenKeyChain, so I'd have to do some reading and playing with it before I can be of any assistance.

To enhance user interface, we could even hide this encryption feature inside "Advanced", so only users who know they want it can enable it.

As for org-crypt, it should be just a matter of tagging notes. As for org.gpg files, they'd be loaded and decrypted. So I think that the only new UI piece we'll need is for telling Orgzly to store notebook encrypted. Unless it came from org.gpg file in which case it would be linked to it and the info is already there.

Encrypting entire files should probably be easier to implement and it's a good start. I personally don't use org-crypt, but I do have org.gpg files. I don't think #202 is a duplicate, though some code working with OpenKeyChain/keys/etc. will probably be shared.

@hyiltiz
Copy link

hyiltiz commented Oct 4, 2018

Great! Thanks for the feedback. I personally also use org.gpg; it also has a benefit of being able to decrypt this file anywhere with a working gpg installation (and keys if encrypted to one). I've never done mobile development before, but the following link mentioned in #202 seems a very useful start:
https://github.com/open-keychain/openpgp-api/blob/master/README.md

So, to work with org.gpg file, I think the following needs to be implemented. Can you @nevenz tell us how/which functions of orgzly would each action interface with? If it is possible to abstract away the platform, I may even be able to implement it.

Features/actions needed:

  1. When opening a file (Notebook) with .gpg suffix (does Android have file type detection like file? That would be better than detection based on suffix), send the file handle/URI to OpenKeyChain. I've heard this kind of across-app interaction is called "sending an intent".
  2. Wait for OpenKeyChain to send a handle/URI back for a decrypted plaintext. If OpenKeychain will keep the decrypted content in its own private storage/memory, find a way to access it; if it sends plain text (as steam or whatnot), find a way to secure it from getting peeked at by other apps. (Hopefully, stuff like this won't happen in Android by default).
  3. Create a record (such as a metadata tag like gpg) (as some metadata) of this plain text Notebook as .gpg.
  4. When creating a new file/Notebook, if its name has .gpg suffix, then do the previous step.
  5. When saving a Notebook/file with the record mentioned above, send the plain text file content to OpenKeychain.

I've noticed that if you tap the vertical three dots (Options button) of the Fennex browser, a large button with the icon of OpenKeychain will show up, which when clicked, will bring up a OpenKeychain encryption window, and put the URL of that tab as the content. That seems to be something we could take a look and see how they interfaced.
screenshot_fennec_f-droid_20181004-191854

@nevenz
Copy link
Member

nevenz commented Oct 8, 2018 via email

@hyiltiz
Copy link

hyiltiz commented Oct 9, 2018

Thanks for the pointers! Answering some of your questions.

  1. Create a record (such as a metadata tag like gpg) (as some metadata) of this plain text Notebook as .gpg.
    What do you mean by this? Flagging the notebook as the one that will be kept encrypted?

Yes. Just a flag for the notebook for encryption. This was the same as your suggestion previously;

  1. When creating a new file/Notebook, if its name has .gpg suffix, then do the previous step.
    I don't think user should worry about suffix and encryption at this point. I think there should be an option when creating a repository to set a per-repository preference and also a possibility to set it per-notebook.

I am skeptical about the benefits of keeping "gpg" under the hood, as most users who directly interact with GPG are already confused by it (public key cryptography is not "intuitive" enough for some). If we make it explicit that we use GPG (whether by suffix or not), then the users will have a chance to look up stuff if needed. Currently, the best interface might be an option to "show enable encryption" in Advanced Settings, then only show a checkbox for "enable encryption" for a notebook. It should be possible to encrypt a file (or even repository) after creating it (imagine a scenario where your notes were random stuff, but at some point you decide to write something you'd like to keep encrypted, and its content is related to the note so doesn't quite make sense to create a new notebook just to encrypt it).

Can you also point to a class template that could performs similar operations (e.g. its instance properties and methods)? Thanks!

@nevenz
Copy link
Member

nevenz commented Oct 10, 2018

I don't think user should worry about suffix and encryption at this point. I think there should be an option when creating a repository to set a per-repository preference and also a possibility to set it per-notebook.

I am skeptical about the benefits of keeping "gpg" under the hood

I'm contradicting myself above somewhat. I was just suggesting not to use extension for anything when creating a notebook, as it doesn't have a meaning at that point - user might not be syncing/exporting notebooks at all.

So just a checkbox (mentioning GPG is fine of course) would be better to flag a notebook as should-be-encrypted-if-it-ever-leaves-db.

Per repository setting would basically just flag notebooks like this automatically.

Currently, the best interface might be an option to "show enable encryption" in Advanced Settings, then only show a checkbox for "enable encryption" for a notebook.

I think this might be too many steps. But perhaps right there, in the new-notebook dialog, a collapsed "Advanced" item list could be added with items such as encryption, title and other Org mode in-buffer settings in the future.

Can you also point to a class template that could performs similar operations (e.g. its instance properties and methods)?

There's nothing similar in one place that I can think of. Perhaps closest thing would be importing a notebook, which opens a system browser by sending an intent and then waits for the result. You can follow ACTIVITY_REQUEST_CODE_FOR_BOOK_IMPORT in MainActivity for that.

@dukebarman
Copy link

What about basic symmetric encryption support from MobileOrg for iOS https://mobileorg.github.io/documentation/#encryption?

@nevenz
Copy link
Member

nevenz commented May 15, 2019

What about basic symmetric encryption support from MobileOrg for iOS

Worth checking how it's done I guess. But it sounds closer to #202 I think.

@ryanpeach
Copy link

So do org.gpg files currently work or is it not yet supported?

@heinzelotto
Copy link

I would like to take a shot at it. I already did some experimenting using the bouncycastle cryptography library and managed to get symmetric whole-file encryption for repository storage working. During sync orgzly then encrypts each local file.org into a PGP tempfile and stores that as file.org.gpg in the repo. During retrieval that process is inverted. Emacs on my desktop was then able to transparently read and write to these .org.gpg-files (without user interaction thanks to auto-encryption-mode).

How the feature could possibly be like:

  • Whole file encryption/decryption at the repository gateway, with the goal that remote files are always stored encrypted.
  • PGP file format, with the goal of simple emacs interoperability
  • togglable per repository (have to take care about migrating files here when en-/disabling encryption or changing the key)
  • Symmetric encryption, with the goal that the user only has to share a passphrase between devices and no keypair management is necessary (see below for discussion).
  • Dependency on the bouncycastle library, with the goal that the user does not have to install openkeychain (also see below).
  • A non-goal of this approach is local confidentiality. I. e. the feature does not protect against attackers that control the phone, only attackers that control the repository. I also see no problem with storing the orgzly-encryption passphrase or orgzly-encryption keypair in application storage without extra security precautions. This makes the feature easier to use (for instance by not having to enter passwords when taking or reading a note).

Regarding the cryptography provider and cryptography choice:

  • Emacs supports transparent encryption and decryption through GnuPG (gpg), both symmetric and asymmetric. GnuPG uses the PGP container format to store encrypted files. This seems like a good choice for file encryption since gpg is available on many computers.
  • Android unfortunately doesn't natively support file encryption with PGP. Even though Android supports the symmetric cipher AES, just storing the encrypted data without container format is not enough, for instance because the password based key derivation parameters (seed and hash iteration count) which are used to generate the AES key from the passphrase are necessary for decryption.
  • Symmetric encryption can be used with a library such as bouncycastle (the jar containing the PGP functionality is 300KB big, would this be within bounds?).
  • Asymmetric encryption and the necessary key management would preferably be offloaded to Openkeychain which would have to be installed on the phone. For the special case of integration with openkeychain for file encryption without user interaction the library openpgp-api is necessary (unsure how big their jar is, but can't be large).
  • Openkeychain can also handle symmetric encryption, but I think it might not be implemented in the openpgp-api. Likewise, bouncycastle can also encrypt asymmetrically, but then we would have to do key-storage by ourselves.

I am leaning towards symmetric encryption via a passphrase that is just stored in the orgzly settings and no external openkeychain dependency. This way the entry barrier would be as low as possible, the user would just have to enter a passphrase (or accept a random auto-generated one) in order to store their files securely on dropbox etc.

What do you think?

@hyiltiz
Copy link

hyiltiz commented Nov 30, 2019

Symmetric encryption is a very good place to start, for reasons you mentioned here and earlier. Please do give it a try!

@fullstopslash
Copy link

fullstopslash commented Nov 30, 2019 via email

@hyiltiz
Copy link

hyiltiz commented Dec 1, 2019

@fullstopslash Unless I severely misunderstood my own proposal posted a year ago or @heinzelotto's, no one is proposing to "remake security".

OpenKeychain as a separate app doesn't integrate well, if at all, with orgzly: consider a file secret.org.gpg created in Emacs and synced to Orgzly via Dropbox. To open it in Orgzly, you'll need to somehow read that file or copy its contents into OpenKeyChain then copy it out over to Orgzly, do your secret business, then go through OpenKeyChain again. We are trying to automate this process as much as possible.

With your expertise in security and understanding of OpenKeychain, we may be able to get there soon enough?

@fullstopslash
Copy link

fullstopslash commented Dec 1, 2019 via email

@heinzelotto
Copy link

I implemented an initial version that can be used to encrypt notebooks in Dropbox repos! Notebooks are symmetrically AES-256 encrypted in the PGP format.

Encryption and decryption is done using the bouncycastle OpenPGP API. API usage code is taken from OpenKeychain (also GPLv3) since at the moment they don't offer an API for symmetric encryption (there is an open bug open-keychain/open-keychain#2536).

In the end I decided in favor of symmetric encryption since it is easier to implement and since a passphrase is easier to handle than a keypair. It can simply be typed into another device (e. g. to access the files via emacs as well), whereas the unwieldier keypair would have to be transferred across some other (possibly insecure) channel.

For now the passphrase is stored as part of the orgzly app settings.

@georgjaehnig
Copy link

I support very much the approach of using OpenKeyChain, and with asymmetric encryption (at least as an option).

If there are questions about implementation, have a look at https://github.com/android-password-store/Android-Password-Store that exactly implemented this approach (even incl. a seamless Git synchronization).

And I can't see yet why Orgzly should be a different use case than Android Password Store in practice.

@fullofcaffeine
Copy link

I implemented an initial version that can be used to encrypt notebooks in Dropbox repos! Notebooks are symmetrically AES-256 encrypted in the PGP format.

Niiice! Can you point us to the PR?

@hyiltiz
Copy link

hyiltiz commented Oct 6, 2021

@heinzelotto That sounds fantastic! We can do well with symmetric encryption for now. It is qualitatively better than having no encryption at all. With the feature integrated, it should be possible (and easier than starting from scratch) to expand it to support asymmetric encryption later too.

@fullofcaffeine
Copy link

@heinzelotto Hi! Did you ever release this as open-source somewhere? I'd be thrilled to have a look and use it myself!

@heinzelotto
Copy link

@fullofcaffeine You can find my progress in #855. Maybe if @nevenz thinks this looks promising I could invest some more time to make it mergeable again on master. Personally I have been using this PR (as well as the previous attempt in #687) successfully for over two years to encrypt my notebook backups on dropbox.

Gigahawk pushed a commit to Gigahawk/orgzly-android that referenced this issue Nov 2, 2023
Update whats new intro and keep link to original repo
@tomasdurham
Copy link

As a simple user, I also have the need for encryption. Can someone tell me if the issue is being pursued? Is it now working with OpenKeyChain? Thanks for an answer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests