Encrypting emails with PGP and WordPress
WordPress out of the box is a pretty secure application, that is not to say it doesn’t have faults, but it does on the whole a reasonable good job on the security front out of the box*. If you are looking for WordPress security guides this is not the place to start.
One area that WordPress could be considered to fall down is sending data in plaintext via emails, and of primary concern would be passwords. It’s important to note the passwords are not stored in plaintext in the database, they are one way hashed, but prior to hashing by default WordPress sends the user a copy of the password. Now it makes sense to email the password as chances are WordPress has randomly generated the password, and it has to get this password to the end user. As this is a randomly generated password, most people simply login and change it as soon as they receive it, there are plugins available to enforce this policy.
The most likely attack vectors against the standard password sending process are to gain access to the persons mailbox, intercept the plaintext packets en-route or compromise the email address in WordPress (change it). Again the risk of intercepted plaintext packets while technically easy to do is highly unlikely, the attacker would need to be actively looking for those packets, in other words such an attack is most likely personal or directed (such as in a corporate environment) far more likely is a compromised mailbox. In reality an attacker is simply better off brute forcing their way in through the wp-admin login screen.
Compromised mail boxes is a truly terrifying event, just think about it for a moment. Chances are your banking, PayPal and just about every service you use probably use some sort of password reset mechanism that relies on the concept of only you having access to your email. If this is no longer true it really wouldn’t take long for our lives to unravel. What a lovely thought!
Pretty Good Privacy (PGP) is a public/private key based encryption, while primarily discussed relating to email, it can be used to encrypt and decrypt pretty much anything. What makes it so useful, is for it to work we only need to know the receivers public key.
Public/Private key cryptography all works on the same principle, a user generates a public/private key, this is normally 2 very long strings of characters, the private key is stored somewhere very safe (I mean really safe, if you lose it you won’t be decrypting anything for a long time) and ideally secure. Private keys are in the eyes of many countries treat like passwords, so for example in the UK you can be prosecuted for failing to provide your private key to authorities if they have a court order. Forgetting your private key could send you to jail for 2 years in the extreme cases, but a more likely means you will not be able to access encrypted data. However it’s both a scary and laughable thought you might go to jail for failing to provide a private key you forgot so the police can read a spam comment sent from your site for approval.
The public key on the other hand you can openly distribute, you will often find public keys attached to or at the bottom of emails, on websites’ contact pages etc.
When two parties want to communicate securely, the sender, grabs the receivers Public Key and uses their encryption software to encrypt the content, as part of this process they put the receivers public key in and the output can now only be decrypted by the receiver using their private key. Not even the sender can read the encrypted contents once it’s encrypted. So they can now openly send the data using their preferred means, such as email, and the receiver simply passes the encrypted content through their encryption software putting in their private key and often a password and the file decrypts.
The important point, is that during transit the data can be intercepted, but only if you have the private key would it do you any good. Traditionally the encryption software and private key resides on the receivers computer, not the mail server, so you would need to compromise one of the end points to gain access, or spend a lot of processing power brute forcing the contents if intercepted in the middle.
The name Pretty Good Privacy is very apt and pragmatic name the system is not foolproof but it does a remarkably good job of protecting data.
These days when we refer to PGP as a standard we usually mean the OpenPGP standard, which defines how the system should work, PGP the name and the software suite was is owned by Symantec.
Instead most people actually use GPG (GnuPrivacyGuard) which is an open sourced alternative that makes use of OpenPGP specification, so when we say PGP normally what we mean is GPG.
If you think that’s a bit weird, remind me to talk to you about why you don’t use SSL ¦
Anyway, after the how it works and history lesson, why would we use it with WordPress?
The 3 big scenarios the PGP can be used inside a WordPress application (or any application):
- Encrypt outgoing sensitive emails
- Storing sensitive details
- Storing details only the user needs to have access to
As we have already discussed the potential abuse of the password management system in WordPress is relatively minimal. There are plenty of other things to worry about when it come to hardening the box before you look at encrypting your email, however there are times where this might be appropriate. For example, I worked on a site run by charity where in certain situations personal information regarding children was sent by email, in this situation encryption was appropriate.
Similarly there may be times, all be it rarely, where data is stored in WordPress that should only be read by the user. For example on uber paranoid membership sites, content can be created and encrypted on the fly for users with their private keys. Perhaps a more realistic scenario would be for downloading binary encrypted file such as a zip or video, only the person with the private key could access this file. Of course once unencrypted they would be able to share the file. Another alternative could be to use WordPress as a secure data dump location for files (in a similar setup to the infamous Wikileaks site) In this scenario the site doesn’t store any keys, just the content if the server is ever compromised the content remains secure.
Getting started with PGP
So let’s have a bit of a play and create a plugin that will:
- Store a users public key in usermeta
- Encrypt all emails sent to a user who has a public key, using their key.
I’m going to make a wild assumption that you can google how to get started with PGP on the client end, either by installing your favourite extension for your mail reader, or if you use webmail a browser plugin. These normally generate keys for you as well.
The key we are interested in is the public key as this is the key we will upload to WordPress. These are normally large lumps of ASCII text. To upload we create a text area in user profile and then save the result to usermeta.
Once we have the key in the database we want to use it to encrypt our emails. There are a couple of existing WordPress libraries available for working with PGP:
- GnuPG PECL Library – http://www.php.net/manual/en/book.gnupg.php
- php-gpg – https://github.com/jasonhinkle/php-gpg
The first GnuPG is a PHP extension, that works directly with GPG software on the server, it allows both encryption, decryption and signing. The second is a pure PHP implementation for encrypting only because it’s pure PHP php-gpg has no dependencies and can be used on more or less any WordPress stack.
For this example I’m using php-gpg and it’s as simple as:
//load lib require_once 'libs/GPG.php'; $gpg = new GPG(); // create an instance of a GPG public key object based on ASCII key $pub_key = new GPG_Public_Key($key); // using the key, encrypt your plain text using the public key $encrypted = $gpg->encrypt($pub_key,$content);
So it’s taking two variables, $key which is the ASCII representation of the public key we stored somewhere and $content, the content we want to encrypt.
So putting this into a plugin, you can create something like this mini plugin.
In this case we are hooking onto the filter
add_filter('wp_mail', array($this, 'filter_email'));
Checking if the user has a stored public key if so using that key to encrypt the contents of the email with it and send it on it’s merry way.
Note you can only encrypt the body of the contents, other parts of the email, subject, receivers etc. will still be sent in plaintext.
So why isn’t everyone using PGP?
Well one reason is it’s relatively complex to set up, while I skipped over setting up your keys in this tutorial, every software, browser extension has it’s own way to generate and store keys, some more sane then others. In addition there are different ways to generate keys and some software won’t recognise certain keys. It’s also a lot of faff, I need to send you my public key before we can talk etc. there isn’t a standard Public Key discovery protocol so this process is still a manual one. There is however hope, Google have announced a project called End-to-End which is a browser plugin to help bring openPGP to the masses. It’s still very early days, but it might see more widespread adoption. Unfortunately it’s using a method for generating keys that is not compatible with the example above, which only supports DSA and RSA keys not EC ones, starting to see the problem? Also putting on tinfoil hat on for a moment, having Google being your mail server and providing you with software for encryption especially with recent revelations regarding big corporates and government spy agencies might make you a little concerned. It’s probably an urban myth but one quote supposedly from Google was that they would only support PGP when they were sure their contextual adverts would still work…
So that’s PGP encryption in a nutshell, one area I didn’t cover at all was signing using PGP a method for verifying the identity of the sender, which has practical applications for verifying users, data and even potential for use as a replacement login system. That is as they say a story for another day.
Finally just want to quickly say thank you to Glenn for sense checking the post for me, when writing about security topics, even covering basic concepts like above that you know well it’s always a good idea to have a second pair of eyes make sure you don’t say something that could be misunderstood. So if you want me to look over your WordPress security and Performance posts, then get in touch.
*Disclaimer: Nothing is 100% secure, and just because something is ok, doesn’t mean you shouldn’t take appropriate additional steps to secure your sites.