Create a gist now

Instantly share code, notes, and snippets.


Asymmetrical encryption with GnuPG

If you're not using asymmetrical encryption for your backups you should start immediately.

With asymmetrical key encryption, other hosts and people can encrypt data that only you can read, meaning that you don't have to share a secret key with anyone and you can distribute the public key freely. This is how public-key cryptography works.

At Elastica this is how we do backups. Every host gets preseeded with one of our strong backup keys. This allows them to gobble up sensitive data and store it in places like S3. If our S3 account was compromised then then intruder would just have a bunch of encrypted files that would take them 20 years of computing power to decrypt.

Since decryption speed is not an issue with cold storage backups, I recommend the maximum 4096 bit lengths.

Here's a quick guide to creating a strong crypto key and encrypting some files.

Generate the key:

[stephen ~/docker/webby]$ gpg --gen-key
(follow the prompts)

If you'd rather do this automatically or in a script, you can feed the options in:

$ gpg --batch --gen-key <<EOF
    Key-Type: rsa
    Key-Length: 4096
    Name-Real: Stephen Wood
    Name-Comment: For Testing
    Expire-Date: 0
    %secring my_key.sec
    %echo done

You'll want to import the private key on any hosts that you want to be able to decrypt data.

$ gpg --allow-secret-key-import --import my_key.key

Remember to securely delete your secret key if you're not going to put the file elsewhere.

$ srm my_key.key

Encrypting and Decrypting

Encrypting can be done on any host that has your public key. First, import the public key to the local hosts's gpg key ring

$ gpg --import

To encrypt a single file:

$ gpg --recipient --encrypt

Note that the key is referred to as an email address. This is how gpg typically works.

Decrypting the file is easy if you have the private key:

$ gpg --decrypt >

By default gpg will decrypt a file to stdout, so we redirect it to a file. You can tell gpg to decrypt it to the original filename by passing in the --use-embedded-filename flag:

$ gpg --use-embedded-filename --decrypt

Notice that we didn't even have to specify which key to use. That's because gpg will use imbedded metadata in the file to decrypt the key. You can see this information by passing in the --list-packets flag:

$ gpg --list-packets
:pubkey enc packet: version 3, algo 1, keyid 6FC17A3C5E45F65C
	data: [4096 bits]
:encrypted data packet:
	length: unknown
	mdc_method: 2
gpg: encrypted with 4096-bit RSA key, ID 5E45F65C, created 2014-06-13
      "Stephen Wood <>"
:compressed packet: algo=2
:literal data packet:
	mode b (62), created 1416686288, name="",
	raw data: 2171 bytes

Pretty nifty, huh?

Multiple files

Encrypting multiple files is much easier to do via the tar command. Since gpg files are compressed automatically, it's not even necessary to gzip them!

Here's how to encrypt an entire folder:

$ tar cf - some_folder | gpg --recipient
(creates some_folder.gpg)

Since gpg defaults to stdout, we simply need to pass that back to tar

$ gpg --decrypt some_folder.gpg | tar xf -
(creates some_folder)

Other fun things

You can also use your private key to sign a message that others can verify for authenticity.

Let's create a document:

cat > my_message.txt <<MESSAGE
Help! The NSA is after me! They've tapped my phone, TV, microwave, and
Nike Air Jordans! Also the fillings in my teeth won't stop playing episodes
of "This American Life" and Ira Glass is getting on my nerves.

Now let's sign the message:

$ gpg -u --clearsign my_message.txt 
(produces my_message.txt.asc)

You've got yourself a signed document.

$ cat my_message.txt.asc
Hash: SHA1

Help! The NSA is after me! They've tapped my phone, TV, microwave, and
Nike Air Jordans! Also the fillings in my teeth won't stop playing episodes
of "This American Life" and Ira Glass is getting on my nerves.
Version: GnuPG v1


You can verify the message. Even the teeniest change to the file will cause the verification to fail:

# Edited file:
$ cat my_message.txt.asc
Hash: SHA1

Dear friend. All is well here.

And what happens when it's verified?

gpg --verify my_message.txt.asc
gpg: Signature made Sat Nov 22 12:20:18 2014 PST using RSA key ID 23D1A7EF
gpg: BAD signature from "Stephen Wood <>"

Looks like your friend is dead. I'm so sorry.

This can be taken a step further if you've already securely exchanged your public key with your "friend". They can both verify your message hasn't been altered, and also verify that it was sent from you. They just need to verify that the Key ID is the same as the one you've imported.

That's it for now. Encrypt your backups! It's easy to do.

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