When building personal or internal projects, it is common practice to use self signed certificates in order to enable HTTPS support.

Self signed certificates, as the name implies, are certificates which you generate yourself. They are generally frowned on from a security point of view, since although they make encryption possible, as they are not signed by a recognised authority, they make no guarantees about trust.

This means that, at the very least, you’ll get a warning in your browser. Worse, it becomes very easy for an attacker to MITM your connection, since both situations will trigger a warning, unless you manually compare key signatures, you’ll never know.

The good news is that, if the only clients that ever connect to your service are under your control (your own custom client, or a browser on your computers in your office, etc), you can use self signed certificates safely by becoming your own certificate authority.

… So here’s how (mainly for my own reference).

Becoming your own certificate authority

The first step is to generate your own master key and certificate that you’ll use to sign your keys.

Start, by generating your root key. It is very important that you keep this safe as anyone who somehow gets a copy of it could create certificates signed as you!

openssl genrsa -out root.key 4096

Next, generate your master certificate using this key

openssl req -x509 -new -nodes -key root.key -days 1825 -out root.pem

Once you’ve generated this certificate, you need to install it on your clients. How this is done varies from client to client, but most browsers have an option (usually in the “advanced” or “security” section) to install a certificate provider. Have a google for “YOUR CLIENT” and “installing certificate” will usually get you somewhere.

On iOS devices the process is simply a matter of emailing the .pem to yourself and clicking on it, and the device will guide you through installation. This will make it available to Safari, but irritatingly there seems to be no way to install certificates for Chrome on iOS.

To update linux command line apps (incuding curl), copy and rename the .pem to /usr/local/share/ca-certificates and then run update-ca-certificates as root.

Generate your server certificates

Once you’ve installed your certificate authority key on the various computers and devices under your control, you are free to generate as many self signed certificates as you wish. Once these certificates are signed by your certificate authority, they will be accepted as legit by all the computers that you’ve installed your root.pem on.

This will provide not only encryption, but also trust, providing protection against eavesdropping and spoofing.

  • Generate your server key:

openssl genrsa -out server.key 4096

  • Generate a certificate signing request (CSR):

openssl req -new -key server.key -out server.csr

  • Generate your certificate, signing it with your master key:

openssl x509 -req -in server.csr -CA root.pem -CAkey root.key -CAcreateserial -out server.crt -days 365

Install your certificate, in Apache or wherever, as you would any other certificate.

Ok, so here’s an experimental, proof of concept plugin for Idno that provides OpenPGP encryption for form posts between web clients and the server (just in time for Reset the net 😉 ).

It makes use of OpenPGP.js, a pure javascript implementation of the OpenPGP spec. On form submission, the plugin will encrypt all form variables, client side in the browser, before transmitting them to the server.

What this for

Primarily, this is aimed at (partially) addressing a situation where you have an Idno site sitting behind a load balancer/reverse proxy like Squid, Nginx or Pound.

In this configuration it is common for the connection to be HTTPS only between the client and the load balancer node, at which point HTTPS is stripped and the connection to the back-end web server is conducted over HTTP. As we know from the NSA smiley, attacking this point where HTTPS is stripped at the load balancer was one of the ways the NSA and GCHQ was able to burgle customer data from Google’s cloud.

Using this plugin, the contents of the form will be encrypted with the back end server’s public key, meaning that the payload will remain encrypted as it transits through your data centre until it’s final destination, where, if you redesign your system as such, it could be stored in encrypted form and decoded only when necessary.

What this is NOT for

This is not intended to be a replacement for HTTPS.

Encrypting the form on the client does raise the bar slightly, making it much harder for a passive attacker to simply read your username and password as it travels over the wire. However, it does not protect against a more sophisticated attacker capable of launching a “Man in the middle“, or “Man on the side attack“.

Using HTTPS is important, because without it an attacker could insert their own public key into the mix, or modify the javascript sent.

Usage and limitations

The plugin currently piggybacks off of gnuPG to do the decryption on the server end, and so this requires you to perform a couple of configuration steps.

  • Make sure you’ve got gnuPG installed. If the binary isn’t at at /usr/bin/gpg, you can set opengpg_gnupg in your config.ini
  • Generate a keypair for your web server user
su www-data
gpg --gen-key
  • Make sure that the .gnupg directory is not accessible publicly, using a .htaccess or similar, since it’ll contain a secret key!
  • Get a copy of the public key gpg --export -a "User Name", and save it as openpgpPublicKey in your config.ini

Once you’ve done this, activate your plugin in your Idno settings, and you should be ready to rock and roll!

It was enjoyable playing with OpenPGP.js, and I can already think of some other cool uses for it (most obvious might be to enhance my OpenPGP elgg plugin).

Have fun!

» Visit the project on Github...