Email encryption using Nylas N1 and Keybase.io

TL;DR: Want to send encrypted email? Nylas N1 with Keybase.io could be a pretty good starting point. However, the Nylas encryption UX needs a little improvement: it doesn’t display PGP fingerprints, it won’t let you sign emails, and has some quirky bugs.

I’ve been very interested in secure communication lately and I’m very excited to see Nylas and Keybase.io collaborating to create a secure email client. I signed up for Keybase as soon as I got the email from the Nylas team, which announced the integration with Keybase as well as free invitations!

My goal for this little experiment was to see how easy it would be to send an encrypted email, especially for novice users. Unfortunately, it was not as easy as I expected it to be, mainly due to the Nylas user interface, I think. Still, using Keybase as a public-key distribution scheme is definitely a step in the right direction and I’m very excited to see how N1’s encryption UI will improve over time.

Step 1: Install Nylas N1 and get a Keybase invitation

I downloaded and installed Nylas N1 (on Ubuntu 14.04). Then, I set up N1 to work with a newly created Gmail account. After setting up the account, Nylas N1 crashed. I reopened it and it worked.

I enabled the encryption plugin in Edit -> Preferences -> Plugins. Then, I went to the encryption options in Edit -> Preferences -> Encryption and clicked on the Keybase invitation link. I got a Keybase invite!

Step 2: Sign-up for Keybase

Using the invitation from Nylas, I signed up for Keybase on their website and their JavaScript code generated a key-pair for me. The private key was encrypted under my Keybase password and stored on the Keybase servers. Of course, I should’ve gone the extra mile and generated my key-pair offline on my machine, but it turns out users are lazy [1], and if they have a quicker option they’ll take it.

Security: From a security standpoint, generating the key in my browser made me a little uneasy, because I had to assume the JavaScript code that Keybase.io sent me was not malicious and did not steal my password and/or my secret key [2].

Also, I assumed https://keybase.io was not impersonated via a rogue certificate and I was actually talking to the real Keybase [3]. I also trust that Keybase properly hashes user passwords in their database so that a data breach won’t result in compromised secret keys.

So far, I am not sure how this key-pair is related to my other key-pairs generated on different devices where I will use Keybase (such as laptop, desktop, etc.). This remains to be seen, but for now I will call this my PGP key-pair (made up of a PGP secret key and a PGP public key).

User experience (UX): No problems.

Step 3: Proving your Keybase identity on other websites

I started connecting my Keybase.io account with my Twitter, GitHub and Coinbase accounts as well as this blog [4] (see proof here). Keybase calls this process proving your identity on other websites.

How does this work? Using my PGP secret key [5], I have to sign a message which contains my Keybase username and, say, my Twitter account name [6]. Then, I can post this signature on my Twitter account for everyone to see. Importantly, only I can post it because only I have my Twitter password. The philosophy behind Keybase is that end-users can better ascertain who I am (i.e., my PGP public key), if they are able to see my Keybase.io profile as well as a cryptographically-signed connection between this profile and, say, my Twitter profile [7], which Keybase does not control. Since anyone can create a Keybase.io profile in my name and impersonate me, my Twitter profile serves as extra proof that it’s really me who created the Keybase.io account, because only I should have access to my Twitter profile to post the signature, verifiable with my PGP public key.

Also, the tweets in my profile kind of serve to authenticate me; a grad student who tweets about security sometimes. Of course, a sufficiently motivated attacker could also create a fake Twitter for me (and a fake GitHub, Coinbase, etc.) and still trick people, but the idea here is that people who already follow me on Twitter will be able to securely obtain my public key from Keybase because they can see a valid signature that ties my Keybase public key to my Twitter account. People who don’t know about my real Twitter account can of course be tricked using a fake Twitter account.

While this security model is reminiscent of PGP’s web-of-trust model, I think it’s much better because lots of people already “know” each other on websites like Twitter, GitHub or Reddit. Keybase.io essentially leverages these existing connections as well as the security of those websites to enable people to obtain each other’s public keys correctly. Furthermore, Keybase actually bundles up all the public-key bindings into a prefix Merkle tree that is periodically committed to the Bitcoin blockchain. This enables people to audit the system, though at a somewhat expensive cost of downloading the whole Bitcoin blockchain. I would like to look more into the way they structure and chain their trees later.

User experience: No problems. Surprisingly straightforward. Not sure if a novice user will understand this step, but it doesn’t seem like they could get this step wrong, which is what matters. Also, at an intuitive level, I think it’s easier for users to understand this identity proving step, than, say, understand how PGP key-signing and verification works.

Step 4: Exporting my Keybase PGP private key (command line)

This is where I got a little bit lost…

How do I get my Keybase private key? When I signed up, the website generated it, so maybe there’s a way to get it from there. But at first, I couldn’t find an option.

Okay, let’s install the Keybase client and use it to print my private key.

$ curl -O https://dist.keybase.io/linux/deb/keybase-latest-amd64.deb \
&& sudo dpkg -i keybase-latest-amd64.deb

$ keybase login

After typing in my Keybase username and password, the client started generating a new key-pair for my Linux box and another so called paper key-pair derived from a passphrase, which I am supposed to keep secret, as far as I can tell.

User experience (login): The output of the keybase login command was:

_During Keybase’s alpha, everyone gets a paper key. This is a private key.

  1. you must write it down
  2. the first two words are a public label
  3. it can be used to recover data
  4. it can provision new keys/devices, so put it in your wallet
  5. just like any other device, it’ll be revokable/replaceable if you lose it_

This is where I am a little confused… This seems to be a recovery key in case you lose your other secret keys (I assume). I’m not sure how “this can be used to recover data”. Are all my other secret keys encrypted with this paper key so that when/if I lose them, the paper key can help me decrypt my messages? If so, then this should be made clear in the command line output.

Also, what does “wallet” mean here? An actual physical wallet? I assume so, since there’s no concept of a virtual wallet in Keybase and I doubt they are referring to Bitcoin wallets. This should also be clarified in the output, though people who’ve never heard about Bitcoin wallets will probably think this refers to their actual physical wallet. Maybe the message here should be: “Keep this passphrase secret! Put it in a safe place, like your (physical) wallet!”

The last (5th) message is a little confusing. It reads like “This private key, just like any other device, it’ll be revokable/replaceable if you lose it”. The problem here is that the sentence “this private key, just like any other device” does not make any sense whatsoever. A private key is not at all like a device…

I don’t yet understand how this paper key “can provision new keys/devices” but we’ll hopefully get to that later.

I think the command line tool is confusing even for people who know what private/public key-pairs are. It needs to mention that the paper key (i.e., the passphrase) needs to be kept secret (“write it down” is not good enough as I could write it down, lose it, and not understand the implications of it).

For power users it would also be nice to understand how these keys relate to one another: Which keys sign other keys? Which keys are encrypted under other keys?

The sigchain UI is supposed to show some of this information but it’s hard to parse. Specifically, it would be great to know what the prev field of the payload is. It seems to be a hash pointer to a previous chainlink, but I’m not sure how it’s calculated yet [8].

The graph UI also attempts to show (1) how keys and proofs are related and (2) how keys and other keys are related, but there’s no explanation for what the graph arrows mean. With respect to the key and proofs, the graph seems to state that my PGP secret key has signed my Twitter/GitHub/Coinbase accounts and that my accounts have “signed” my PGP public key (HTTPS + backend security of websites basically define a “signature”).

User experience (pgp): After logging in w/ keybase login, I wanted to export my Keybase private key, but because two new (device and paper) keys were just generated for me, I was suddenly confused: Which key am I supposed to export?

Let’s see what I can find out about my private keys using the keybase command line tool.

$ keybase pgp list

Keybase Key ID:  010136221c73731f00d341ac407ca592645fc56a73503f2a875513da072f05e40da50a
PGP Fingerprint: 2848 DBBD 007F BCB0 75B7 97FB 37C1 887D 6E55 CA9A
PGP Identities:
   Alin Tomescu <bla@mit.edu>
   Alin Tomescu <blah@gmail.com>
   Alin Tomescu <blablah@csail.mit.edu>

Okay, I guess I’m supposed to export the corresponding PGP private key and import it in Nylas N1. I still have to understand what the other device and paper keys are for.

Let’s try exporting this PGP private key:

$ keybase pgp export

But that only gives me my public key. How can I get my hands on my secret key? Let’s take a look at the docs a little… The command line docs don’t seem to explain how to export the PGP private key. Maybe this is more of a security feature to prevent inexperienced users from accidentally leaking their keys? Maybe. A Google search revealed that I can just use the Keybase website for this [9] (see here): just click on the “edit” button next to your PGP key on the website and a menu will pop up with an export button.

Apparently, it’s also possible to get the key using the gpg tool (see this and this). So let’s try that as well (my PGP key ID is 37C1887D6E55CA9A):

$ gpg --armor --export-secret-key 37C1887D6E55CA9A
gpg: WARNING: nothing exported

Bummer, doesn’t seem to work even though I should have the private key somewhere on my machine because the keybase sign and keybase verify commands which use it work fine.

Okay, we’ll leave this one for later. For now, I’m exporting the private key from the Keybase website! Keybase tells me my “private key will be password protected with your Keybase passphrase,” so I guess I’ll have to enter my Keybase password in Nylas N1 when importing this key.

User experience: Good enough. Not sure how I missed the “edit” button on the Keybase website for downloading my PGP private key. I would argue that “Export my private key from Keybase” does not really fall into an “edit” operation, so maybe this should be moved. Hard to say whether secret keys should be easier to export, since that could lead to more accidental leaks.

Step 5: Importing the PGP private key into Nylas N1.

In N1’s encryption options, three buttons are available: Paste in a New Key, Import a Key From File, and Generate a New Key Pair. They only mention “key,” no “public” or “private,” so it’s not clear if this can be used to import a private key, a public key, or both.

I ended up using the Paste in a New Key button to install my secret key, as exported from the Keybase website. Although the UI asked for the password that encrypts my private key, it let me add the key without the password. Perhaps, N1 will just ask me for my passphrase every time I decrypt or sign a message? The UI for Paste in a New Key is weird: after I imported the private key the dialog remained there, instead of nicely disappearing.

I am confused by the fact that I am allowed to add my own public key to the list of public keys I have. Is this necessary? My public key is already contained in my private key (even the Keybase UI for exporting my private key acknowledges this). Thus, I only added my private key.

Annoying bug: The UI lets you associate email addresses with the public and private keys. Yet, if I associate an additional email address with my own public key then I cannot associate it with the private key anymore, receiving an error “A PGP public key for that email address already exists.” But if I delete the public key association, I can successfully create the private key association and then recreate the public key association as well. This seems like a bug.

User experience: Needs improvement. I don’t think I should have to import my own public key when my secret key is there already. Also, is there a point in associating different email addresses to the two halfs of your PGP key-pair? Also, PGP fingerprints should be displayed for out-of-band verification.

Step 6: Signing a message with my newly installed secret key

I opened a compose windows, to send myself a signed PGP message.

Uhh… there is no signing in the UI :( Just encryption. Bummer. Also, in the process, I’ve managed to crash the N1 compose window (N1 kept running though). Perhaps signing is done by default when encrypting?

User experience: Lacking. Ability to sign should be there. Bright side: At least I could tell there’s no signing and only the compose window crashed.

Step 7: Encrypting a message for myself

Let’s try encrypting a message to myself instead of signing.

I wrote an email and clicked the lock button that is used to encrypt. I looked up my Keybase username, clicked “Import Key”, but got an error saying:

There are no PGP public keys loaded, so the message cannot be encrypted. Compose a message, add recipients in the To: field, and try again.

First error

The message did not encrypt. So I clicked the lock button again, but got the same error:

Second error

Pressing the lock button a third time encrypted the body.

Great success!

That’s annoying. Not sure what happened there, but I was able to reproduce this bug many times.

Let’s try composing again to myself. This time the lock button seamlessly encrypts the email’s body. However, the compose UI does not display the fingerprint of the public key I encrypted under. This is problematic, I think, as it could make man-in-the-middle attacks easier to pull off.

Encrypted email sent! But to whom? Fingerprints are not displayed anywhere. And is it also signed? Can’t tell.

Unfortunately, I can’t test decryption because N1 doesn’t seem to want to deliver messages to myself, whether they are encrypted or unencrypted. Hopefully, I will follow up with another post when friends sign up for Keybase and I can test N1 with them.

User experience: Needs improvement. Crashes and errors happen for no reason seemingly. A way for user to easily see key fingerprints is needed, both in the encryption options and in the compose window. As a user, I can’t easily tell if my emails are being signed or not. This is problematic because I should know what security guarantees I am getting and if my messages are deniable.

Thoughts on Nylas N1

I think the guys at Nylas are doing very interesting work trying to build an extensible email client, particularly because N1 could one day be extended to support long-awaited email security features.

Unfortunately, I don’t think that day is here yet; there are currently too many problems with N1:

  • weird and error-prone UI for importing PGP secret keys and public keys
  • random crashes
  • weird UI bugs, like error dialogs disappearing if I click outside them
  • weird and error-prone UI for looking up public keys when composing
  • lacking security UI: no fingerprints, no signatures
  • encrypted messages I sent to myself from N1 did not arrive in my N1 inbox
  • encrypted messages I sent to myself from N1 did appear in my Inbox (the Google mail app) inbox for a split second and then disappeared
  • sent encrypted messages were not saved neither in N1 nor in Google’s Inbox
  • sent plaintext messages were not saved neither in N1 nor in Google’s Inbox

Thoughts on Keybase

I’m excited to see Keybase tackling the very hard problem of verifying if some public key x belongs to some real-world person p, and doing so without requiring users to trust a single entity like Keybase itself. I think the idea of posting these PGP signatures on your social media profiles could be a promising way to prove one’s identity, especially as service providers like Facebook, Twitter, Github, etc. become more serious about their security and other techniques like (enhanced) certificate transparency further improve web PKI.

I would like to see more in-depth descriptions of the Keybase crypto. At first glance, I don’t understand their key hierarchy and how their prefix trees are structured, like what’s in the leafs, how are they chained, etc. I think they do go the extra mile to explain things though, which is to be appreciated in an industry full of snakeoil products that just throws around words like “integrity”, “encrypted” and “authenticated” to entice potential customers.

Also, I can imagine that from a business standpoint it might not make a lot of sense to actually describe the crypto in detail.

Conclusion

N1 and Keybase are bringing us closer to email encryption with an improved public-key distribution scheme integrated in an email client. From this limited experiment, N1 does not seem very usable at the moment as an encrypted email client. I still need to test N1 with someone other than myself though, to see if it performs better. I am sure N1 will improve in time though and I’m excited to see Nylas and Keybase bring email encryption to the masses.

Please, do give N1 and Keybase a try yourself. It’s possible experiences will vary across operating systems.

Footnotes

  1. To be read as, “I am lazy.” 

  2. Sigh. I wish I had the courage to use the pgp command line manually. 

  3. Hi, NSA! 

  4. This came in hand to figure out where to put the keybase.txt file. 

  5. I think… At, this point I have no other keys! 

  6. For simplicity, I am ignoring other things it contains. From what I can tell though, it does not contain the Merkle root of the Keybase site-wide tree. More on this later. 

  7. See Keybase proof in this tweet 

  8. Explained a little here, but probably best to read the source code. 

  9. Facepalm. 

Written on June 15, 2016