What is gpg?

This is my second post on my What Is X series and today I'd like to write about GnuPG - The GNU Privacy Guard, often shortened to gpg, which is also the name of the program I'll be showing you in this post. If you'd like to follow along, go ahead and install gpg. You'll likely find it in your chosen package manager. The examples I'll be running through here will be using gpg version 2.2.13 running on GNU/Linux.

So what even is gpg? It's an free and open implementation of the OpenPGP standard. With gpg, you can encrypt, decrypt sign and verify messages to secure your communications online. I'd like to give you a high level overview of how you can do this. If you're reading this, I'd expect that you are somewhat comfortable in a terminal, but no prior knowledge of cryptography is assumed. I'll keep this nice and simple.

You're going to need some keys. When you generate a new key pair, you'll be left with a public key and a private key. The tl;dr here is, under no circumstances should you ever give somebody your private key.

$ gpg --generate-key

gpg (GnuPG) 2.2.13; Copyright (C) 2019 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Note: Use "gpg --full-generate-key" for a full featured key generation dialog.

GnuPG needs to construct a user ID to identify your key.

Real name: Key McKeyface
Email address: [email protected]
You selected this USER-ID:
"Key McKeyface <[email protected]>"
Change (N)ame, (E)mail, or (O)kay/(Q)uit? O

We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
gpg: key 07717F57B6E6DDA1 marked as ultimately trusted
gpg: revocation certificate stored as '/home/keymckeyface/.gnupg/openpgp-revocs.d/16299ADA4C393923AE179D0407717F57B6E6DDA1.rev'
public and secret key created and signed.

pub   rsa2048 2019-03-29 [SC] [expires: 2021-03-28]
    16299ADA4C393923AE179D0407717F57B6E6DDA1
uid                      Key McKeyface <[email protected]>
sub   rsa2048 2019-03-29 [E] [expires: 2021-03-28]

So at this point, you'll have generated your keys! You may send your public key to anybody, host it online, put it anywhere etc... but your private key must remain a secret to you only. Let's have a look at our new key:

$ gpg -k
pub   rsa2048 2019-03-29 [SC] [expires: 2021-03-28]
    16299ADA4C393923AE179D0407717F57B6E6DDA1
uid           [ultimate] Key McKeyface <[email protected]>
sub   rsa2048 2019-03-29 [E] [expires: 2021-03-28]

So now that we've generated our key pair, lets I'll quickly explain what you can use each key for.

If you have someone else's public key, you are able to encrypt a message that only they will be able to decrypt. The message can only be decrypted by the person who has access to the corresponding private key. This is super cool, as it allows you to use basically any means of communication while knowing that your private message cannot be snooped on or intercepted on the way to it's recipient.

Say for example you wanted to send me a secret message, you must first import my public key:

$ curl https://storage.hazbo.co.uk/keys/pubkey.asc | gpg --import

Now if you were to run:

$ gpg -k

You'll see my key added to the list! Let's now create our super secret message:

$ echo "Hi Harry, this is my super secret message to you." > msg

We must now encrypt our new file, msg using my public key:

$ gpg -ear [email protected] -o msg.asc msg

Let's break this command down a little. We are passing through 4 options here. e, a, r and o. E stands for (you guessed it) encrypt. A stands for ascii armored. This creates ascii output which we can then copy and send to our recipient. R stands for recipient! So after passing -r we must then provide the user we would like to be able to decrypt this message, in the above case that'd be me. And finally O stands for the name of the file we wish to output this message to. We then pass in the name of the file we'd like to encrypt, which is msg.

Simple, eh? We can now have a look at our encrypted message:

-----BEGIN PGP MESSAGE-----

hQEMA7uBVVw2uuquAQf+NK34hrN7NoL0TT0BX2dFJyTD9XPJWibeq/yW+sKsmUYw
6m1ovynJwksXNuDeErjupuGSEkRfyX5Rt07ENZNJVfj3M/LkW6A5AeJfJ2GrVqRK
nIQGP2K6fBhZaVHyB7uCIQs+xvTZEZ+zmwpZfy4BRWDNlhB0OxUmNiLGwgDdDGW2
jG/Q+7oUTDzoZ+WNukgT1ve9lINlErlW/W0a8VCndPe/o5no8pyRQ1EloOunaJQC
fsNDTkSZrC8J6elcQhHpWNFkiS8bKSlosdhyrDo9DFjm5w5w9Lwq2Qn/zt1WCf7x
E/oixyZ2JzxD798Yuwdz0HcfyK9GGMCL3bJ8wRfVkdJuATgUVP2afcvrkSG6CAdW
c7zyJXTFt27ub/B+tXJb+Sl+wDfGBvEJPnKfPKcpTAgrnaZP2hWSy9ze+4Op3yXY
qMr5ytWXNdfmAaW2refEv/BcffL28yncOKzZ1S591Wc2JXYnU6CxWgORTTUQqmg=
=ORjX
-----END PGP MESSAGE-----

So if you were to send me this, I and I alone would be able to decrypt this using my private key.

So how would I go about decrypting this? It's actually very simple:

$ echo "-----BEGIN PGP MESSAGE-----

hQEMA7uBVVw2uuquAQf+NK34hrN7NoL0TT0BX2dFJyTD9XPJWibeq/yW+sKsmUYw
6m1ovynJwksXNuDeErjupuGSEkRfyX5Rt07ENZNJVfj3M/LkW6A5AeJfJ2GrVqRK
nIQGP2K6fBhZaVHyB7uCIQs+xvTZEZ+zmwpZfy4BRWDNlhB0OxUmNiLGwgDdDGW2
jG/Q+7oUTDzoZ+WNukgT1ve9lINlErlW/W0a8VCndPe/o5no8pyRQ1EloOunaJQC
fsNDTkSZrC8J6elcQhHpWNFkiS8bKSlosdhyrDo9DFjm5w5w9Lwq2Qn/zt1WCf7x
E/oixyZ2JzxD798Yuwdz0HcfyK9GGMCL3bJ8wRfVkdJuATgUVP2afcvrkSG6CAdW
c7zyJXTFt27ub/B+tXJb+Sl+wDfGBvEJPnKfPKcpTAgrnaZP2hWSy9ze+4Op3yXY
qMr5ytWXNdfmAaW2refEv/BcffL28yncOKzZ1S591Wc2JXYnU6CxWgORTTUQqmg=
=ORjX
-----END PGP MESSAGE-----" | gpg -d

the -d meaning (yep, you guessed it again) decrypt. You could also output the message to a file if you wanted to, by passing the -o option like we did earlier. (Remember, you won't be able to decrypt the above message, as it is only meant for me.)

You can try this process out for real, using my public key right here in the browser:

Simple, right? So how do I know that it was actually you that wrote me a message? That's where signing comes in. By signing a message, you're putting your stamp of authority on it. And of course the only way you can do this is by using your private key, as you are the only one who has access to it. So let's do that:

$ gpg --clear-sign -o msg.asc msg

In this case, we are going to --clear-sign the message, which means it will be readable, but will include a signature that only you could have generated. We can also sign an encrypted message, using the same command as we used earlier, but by passing the -s option to it also:

$ gpg -sear [email protected] -o msg.asc msg

You will of course be asked for your passphrase in order to sign the message. If you were to recieve an encrypted + signed message like this, you can use the exact same method to decrypt it as outlined above to see what it says.

This has been a very breif overview of how you can use gpg. I'd suggest you read through the man pages, as there are a lot more things that can be done.