PGP Never Gonna Give You Up

(Summary: Cryptographically signing messages with my long-term PGP keys is too important to give up. Doing this on my Android telephone is easier than I thought. You should strengthen your secret key encryption if you’re also going to do this.)

Recently, Filippo Valsorda, cryptography expert and TLS guy at Cloudflare, wrote that he was giving up on PGP, or at least on long term PGP keys.

I agree with many of his points, especially the complexity of managing those keys, lack of forward secrecy (if someone were to steal my keys, they could decrypt all past conversations, unlike for example Signal) and accessibility (how do you verify a message with a baby on your left arm and your telephone in your right?). More generally, it makes a great deal of sense to make your security a moving target, as one of the Ars Technica commenters astutely summarised Filippo’s ideas.

Cryptographic signatures FTW

However, in spite of these factors, I am not yet ready to give up my PGP long-term keys.

Why is that?

Well, one of the most important uses of my long-term PGP keys is to cryptographically sign messages that can be verified by people in my network as having come from my hands.

For example, when I change my phone or re-flash its firmware (this has happened 3 or 4 times over the past two months because Android), I send PGP-signed messages to my main Signal correspondents with our new safety numbers.

With all of these correspondents I have in the past either done some sort of in-person formal PGP signing procedure, or I make use of the web of trust, or I rely on keybase. My business cards even have my key fingerprint on them (yes, I’m one of those nerds).

At their ends, the recipients of my messages are able to determine with an extremely high degree of confidence that I wrote the exact message they opened.

Accessible PGP on your smartphone with OpenKeychain

In terms of accessibility, the post did make me curious enough to experiment with a mobile PGP solution, as I also did have to agree that I’ve in the past often had to wait until I was behind one of my own laptops or workstations to PGP-verify a message.

As my one friend explained on Signal:

It’s tricky to verify a message with a baby in your left hand and a telephone in your right!

OpenKeychain to the rescue!

Strengthen your secret key encryption

Seeing that I was planning on carrying my long-term private keys around on my telephone (BlackBerry PRIV, FDE encryption active FWIW), I had to double-check the security of the secret key encryption.

It turns out that PGP encrypts each of your secret keys with a hash of the passphrase you supply. My passphrase is significantly longer than the average, and consists of random characters (uppercase, lowercase, numbers, symbols). Passphrase length and complexity is by far the most important factor determining the safety of your encrypted secret key.

However, I had the default SHA-1 hash (ouch) with only 64k iterations. Iterating the hash is called key stretching: the passphrase is hashed, that result is hashed, and so on, for very many times, so that the testing of each passphrase takes more time, complicating brute-force cracking approaches.

Inspired by the writings of Chris Wellons who keeps his encrypted secret keys on a public website (!!!), I reconfigured my private key encryption to use 1 million iterations of the SHA-512 hash, and to use AES-256 for the encryption itself:

gpg --s2k-cipher-algo AES256 --s2k-digest-algo SHA512 --s2k-mode 3 --s2k-count 1000000 --edit-key 384435C7E77A4564

After typing that command, enter passwd at the prompt, then follow the prompts. You will have to enter your passphrase, and then enter your new passphrase twice.

You can then check that this operation is successful by using the command gpg --list-packets secring.gpg. My output looks as follows. Most important is that algo is 9 (AES-256), hash is 10 (SHA-512) and protect count in my case is just over 1 million.

:secret key packet:
     version 4, algo 1, created 1376407300, expires 0
     skey[0]: [4096 bits]
     skey[1]: [17 bits]
     iter+salt S2K, algo: 9, SHA1 protection, hash: 10, salt: blabla
     protect count: 1015808 (159)
     protect IV:
     encrypted stuff follows
     keyid: 384435C7E77A4564

SHA-512 is the slowest hash which PGP offers (see these oclHashcat benchmarks for example), which means that each iteration of a brute-force password cracking attempt will take a bit longer / eat more GPU watts, which is exactly what we want. You can increase the protect count for as long as the delay on your smartphone is still tolerable.

However, remember that a stronger and longer passphrase is much better! (so we do both)

Other than that, remember that Android security is far from good, so do as much as you can to keep your phone safe (keep up with OS updates, stay away from unofficial app markets, and so on).

Use your keys with OpenKeychain

I was pleasantly surprised to learn that I could directly import both my secring.pgp and pubring.gpg files from my ~/.gnupg directory. Right after selecting secring.pgp for import, the UI looked like this:

You can see the old 1024 bit key I made in 2000 to use for my Debian activities, and the 4096 bit key I currently use.

After importing your secret and public keyring, you are able to encrypt, decrypt, sign and verify any files or clipboard contents on your Android phone:

So if I receive something like this via Signal:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

Never gonna give you up, never gonna let you down
Never gonna run around and desert you
Never gonna make you cry, never gonna say goodbye
Never gonna tell a lie and hurt you
-----BEGIN PGP SIGNATURE-----

iQFEBAEBCgAuJxxTdGVmYW4gdmFuIGRlciBXYWx0IDxzdGVmYW5Ac3VuLmFjLnph
PgUCWE2aUQAKCRDl/rykoDTdZZgvB/9Yi76C9o7xIgQ/d85WbnKDjNosp5uXzgHm
A2y+cxZDLVNLTMrlCTXOMRulaJMvb3Ocsvi+/gQVUF49fT74EXlZpZvvdTzhQfa2
VvQPjZmf/9PNzB3pgUtEDBwyLC21C6dqU+y7mPk91Aw1m8cKBQUSHmQxa7F/dCFc
DCuWOcXjNt5vLQ2Q8mQBMpHaG9J5+4/0k/GEHAVcm55fzb7o2hJyEVb3EoYy8Pls
khIwJpZVdwyY4FPoLXW3iJYanC5qoOoS81YLCyLEyin0jH56ve05uHbF0XcaNY4h
NupkN2D+Dt4X2m2FXieM27eG/Ty9hVx7n7B3pT4P9KqeFDX8hQ/q
=c7j9
-----END PGP SIGNATURE-----

I long-press, copy the message and then select “read from clipboard” from OpenKeychain’s Encrypt/Decrypt screen, which, if everything checks out, shows me the following message:

I can now rest assured that this specific buddy of mine is never gonna give me up and is never gonna let me down.

Cryptographically signing a message is equally easy, except that you’ll have to enter that long passphrase of yours. OpenKeychain will then make the signed and optionally encrypted text text available for sharing to any app, or for copying and pasting:

Easy peasy, and tested under all sorts of usually-PGP-unfriendly conditions!

Conclusion

Maintaining PGP long-term keys certainly has its issues, but the possibility of cryptographically signing any message so that recipients can establish with high confidence that it originated from you is too important to give up.

With an app like OpenKeychain and sufficiently strong passphrase hashing and secret key encryption, you are able to use your keys with ease from your telephone.

Granted, you are trading in some security for this convenience. However, given the choice between discarding my PGP keys completely, vs. taking these steps, I’ll hold on to my keys for a little while longer.

In order to mitigate the potential damage of one of my long-term keys being compromised, I have resolved to generate and start using a new private key as soon as I run through my current batch of business cards, and to continue rotating like this in the future.

Let me know in the comments what you think. Do you know of a better alternative for remotely verifying the identity and messages of your correspondents?

Installing free Let’s Encrypt SSL certificates on webfaction in 3 easy steps

WARNING: High levels of NERD ahead.

I started using CloudFlare’s free tier on this blog, before Let’s Encrypt burst onto the scene, mostly for their universal SSL. However, as joepie91 recently pointed out, this means that by design, CloudFlare has to decrypt all SSL traffic, and then re-encrypt it to send it to your original site with its self-signed or generic certificate (in my case). Apart from this, CloudFlare is a bit of overkill for this low-traffic site.

le-logo-standard.png

Because I don’t need much of an excuse to try out something new, I used this as my excuse to try out Let’s Encrypt, a fantastic new(ish) service which issues free 90 day certificates to anyone who can verify their domains.

I was shocked with how easy this was on the webfaction shared (non root) hosting I’ve been using for years, and so I had to share.

WITNESS THE GREAT EASINESS:

Step 1: Install acme.sh

These two steps are to be performed whilst SSH’d in to your web host.

First we install the wonderful acme.sh by following the one-liner on its website:

curl https://get.acme.sh | sh

At this junction, as they say, it’s best to log out and in again, so that the acme.sh alias and environment variable can be setup.

Step 2: Issue shiny new SSL certificate

We then get acme.sh to verify the website using the webroot method, and to request a certificate for the two domains cpbotha.net and www.cbbotha.net:

acme.sh --issue -d cpbotha.net -d www.cpbotha.net -w ~/webapps/wp

The argument following -w is the directory exposed by the website http://cpbotha.net/. Note that this is still http; Let’s Encrypt queries a special file left there by acme.sh to confirm that you actually manage the specified domain.

After a few seconds of progress output, I was left with a shiny certificate (as well as the CSR, key, and so forth) in ~/.acme.sh/cpbotha.net/

Step 3: Install shiny new SSL certificate

On Webfaction, one has to file a support ticket for this. My request was formulated thusly, and was correctly acted upon in about 5 minutes:

Could you please install the following SSL certificate for the website cpbotha_SSL – reachable at https://cpbotha.net/:

  • cert is in /home/cpbotha/.acme.sh/cpbotha.net/cpbotha.net.cer
  • key is in /home/cpbotha/.acme.sh/cpbotha.net/cpbotha.net.key
  • intermediate CA cert is in /home/cpbotha/.acme.sh/cpbotha.net/ca.cer
  • full chain certs is there: /home/cpbotha/.acme.sh/cpbotha.net/fullchain.cer

Thanks!

Update on 2016-10-25

It is now possible to install the new certs all by yourself using the webfaction panel or the API! Read the announcement blog post for more information.

Bonus level: In 90 – k days, simply re-run acme.sh

At any point, you can request certificates for any other domains that you may be hosting on your webfaction.

At regular intervals, or in slightly fewer than 90 days, simply run:

acme.sh --renewAll

To have acme.sh renew any of your certificates that are up for renewal. Just remember to create a new support ticket to have the renewed certificates installed for the relevant domains.

acme.sh cronjob

Unbeknownst to be (I should have read the docs) acme.sh had cleverly installed a user cronjob to check for renewals. When I attempted to renew two of my certs, I saw that it had already done so automatically, so I only had to install the updated versions.

Boss level: htaccess-based redirect from HTTP to HTTPS

Now that I have my SSL setup, I would prefer for users who go to the HTTP site to be 301 forwarded to the HTTPS version. On Webfaction, I can do that with the following addition to the site .htaccess file:

<IfModule mod_rewrite.c>
RewriteEngine On
# we're behind nginx ssl proxy, hence the non-standard check for no-SSL:
RewriteCond %{HTTP:X-Forwarded-SSL} !on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>

Important: webfaction is using nginx as their SSL frontend, so we check for the X-Forwarded-SSL header.

When we can, let’s use Signal instead of WhatsApp.

(Post updated on August 25, 2016. See section at the end.)

Screenshot of Signal.
Signal, the open source messaging and voice calling app that does end-to-end encryption.

The whole world is using WhatsApp to message each other. I often do too, because I want to inter-operate with the rest of the world.

However, WhatsApp belongs to Facebook.

Although Facebook has promised otherwise, the temptation to link all of your WhatsApp messages with Facebook logins (a straight-forward process, as they have the mobile phone numbers of a great number of their users) must be quite tempting to the people at Facebook. Imagine how well they would then be able to target their advertising, based on their access to both your Facebook profile and your private WhatsApp messages!

Fortunately, we now have an open source app, called Signal (available on Android, IOS and the desktop), which performs end-to-end encryption on all messages and voice calls that go through it. This means that absolutely no-one is able to read your messages or eavesdrop on your voice calls, except the intended recipients.

My request is that you get your contacts to install and start using Signal instead of WhatsApp wherever possible. At the very least some of our messages will not be accessible to various large corporations and any other prying eyes. If the security argument is not enough for you, there is one more extremely important topic: Signal handles animated gifs better than WhatsApp, at least on Android. (Telegram supports them on both Android on IOS, but it is by default less secure than Signal). See here the results of my experiments:

Updates

On August 25, 2016, The Verge reported that WhatsApp will now officially begin sharing data with Facebook. They will indeed link up telephone numbers and social networks, meaning that both parties will get a tremendous boost in what they know about you. I don’t want to say I told you so, but I told you so. ;)