Skip to content

Instantly share code, notes, and snippets.

@stephen-mw
Last active August 29, 2015 14:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stephen-mw/c99219218fbfab0c859d to your computer and use it in GitHub Desktop.
Save stephen-mw/c99219218fbfab0c859d to your computer and use it in GitHub Desktop.

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
    Name-Email: smwood4@gmail.com
    Expire-Date: 0
    %pubring my_key.pub
    %secring my_key.sec
    %commit
    %echo done
EOF

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 my_key.pub

To encrypt a single file:

$ gpg --recipient smwood4@gmail.com --encrypt ping.heystephenwood.com.cert
(creates ping.heystephenwood.com.cert.gpg)

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 ping.heystephenwood.com.cert.gpg > ping.heystephenwood.com.cert

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 ping.heystephenwood.com.cert.gpg
(creates ping.heystephenwood.com.cert.gpg)

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 ping.heystephenwood.com.cert.gpg
: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 <smwood4@gmail.com>"
:compressed packet: algo=2
:literal data packet:
	mode b (62), created 1416686288, name="ping.heystephenwood.com.cert",
	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 smwood4@gmail.com
(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.
MESSAGE

Now let's sign the message:

$ gpg -u smwood4@gmail.com --clearsign my_message.txt 
(produces my_message.txt.asc)

You've got yourself a signed document.

$ cat my_message.txt.asc
-----BEGIN PGP SIGNED MESSAGE-----
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.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1

iQIcBAEBAgAGBQJUcPACAAoJEKSJEkYj0afvor0QALvrYflk52NkNmwpq09FM+2x
06RKsmzQgXa8W+3yHpTUlAMhVPoToeETp9wrM4zod+6nmiyan/aqP1QzXq0QC+yc
SEOGIn7r69+d1ybCXHnC2ebbB2pVj8NwH30a6hLNUHlmZ9xGjX4bnqUREIo1booV
MnWqUab7PFjEJ97fVW9b47kpZ+Mi0P8MhphGA+QHzGl56UtDo5wPci8A3TKqfCsq
didoYGAJurVnVIwvjXPkwKnKwL4E0AvTRN5iiiN6Rib+be8Pmy8wUNA7LdwjERO1
H8zVCgyFvOzA16PbdmKJF5nnUAlJASO4ZStUD5z/AIYir9cXuNSlx45FFVse3lFu
yyftQkvJPJbzVdg/JaYswj7vMFPPmRBweFzFZjBqrDu+o1aPWougbOFnU3ZDuf3s
4SmbI7gJDDet7cvYHWn+8doGGI5BpPb0gXjfhW+WBuvMZ01GJbXwychi5d4xC1Qi
XYkd4RgdxxIhyLrO+whWYHFZlI3UY6cPPyyiDjTLR/UCP2IrtdL7gcPJicXGSGG3
EJLjG1mK+nk44QT4oW7Ghha6G1oI2YoqjAWrlWhaSyxlNSv4qw75x5w6WtzoL2yR
mayROMUmmHrBYfgFtgk64X+qcd3Li8/InZUw95A5SnV69r2h5p05fPiE70sgu73R
ozOu9eBEjYDTEb4PYS+5
=JiEL
-----END PGP SIGNATURE-----

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
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Dear friend. All is well here.
-----BEGIN PGP SIGNATURE-----
...

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 <smwood4@gmail.com>"

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