I’ve always wanted to write this blog post someday, but found it quite difficult because even I didn’t know the fundamentals behind GPG, and how it all worked behind the scenes. So it’s extremely satisfying to finally release this today. Of course, since I’m only human there will probably be lots of mistakes. If you notice any, please send them to my email, firstname.lastname@example.org, and I will reflect them in this article. Thanks!
(For an extra challenge, try encrypting your email with my public key so only I can read it! My public key can be found here. Good luck!)
Proof of origin
Picture this: you’ve just finished writing a cool game in Unity, and want to send it to your friend Tom so that he can test it. Unfortunately, things go wrong in the process and a hacker is able to MITM your connection. So when Tom receives your game, he notices that you have also bundled a cryptocurrency miner. He unfriends you and you become an introvert.
So how do you prevent this type of attack? Well, situations like these is why email today is encrypted1. But what if you want to finally release the game? The site can get hacked, the file could be modified in-transit, etc.
That’s why you want to sign your executable, except it’s more secure than the security theatre that is jotting down your “unique” signature whenever you pay by credit card. No, no, signing digitally ensures that nobody else can tamper with your file without breaking that signature. In short, what you sign digitally always stays intact, unless the original file changes.
Whistle-blowers, political activists, and other important figures make use of cryptography all the time to communicate important information that should not be revealed to any third parties. Any sort of leakage could lead to you finding your family at gunpoint.
But encryption using traditional tools require you to share a key, to decrypt the information. You could send the key over with the data you encrypted, but if a third party gains access to the method you used to transport the data, then the data is just as good as it is unencrypted. You could send the keys through a different channel, but what if there is no alternate channels available?
This is mitigated through something called asymmetric cryptography, which we will talk about down below, since it is also related to signing (as we talked about above). But in short, asymmetric cryptography usually involves both a “public” key file and a “private” key file. As the name implies, the “public” key file is the one you distribute and share to everyone in the world. The “private” key file is the one you keep safe, and not show to anybody.
Wait, what is asymmetric cryptography?
When you want to sign something, you take out your “private” key file, then you sign the original file. Then you send out the file to the world. Now, your users can verify the file was signed by you by comparing the file’s cryptographic signature to the “public” key file.
The same goes for encryption, but backwards. Say you are a whistle-blower, and you want to securely send some sensitive documents to a journalist. You would first obtain the “public” key of the journalist, and then use that to encrypt the documents you want to send. Once you send it, the reporter would be able to decrypt the files using his or her “private” key.
But can’t I just use the public key to do whatever?
That’s the beauty of it. The public key can ONLY be used to encrypt files, or verify signatures of files. It cannot be used to decrypt files, or sign files.
Through a lot of mathematical transformations involved in asymmetrical cryptography, which we can thank a lot of mathematicians and cryptographers for, a “private” key cannot be derived from a public key, feasibly. Theoretically, it is possible if you have access to quantum computing. But by that point we would have far more serious problems, so we don’t need to worry about that for now. Just know that cracking asymmetrical cryptography at this stage is feasibly impossible, even with supercomputers. (That’s only if you remember to use a large keysize!)
In short? Asymmetric cryptography is safe to use for a very long time, provided you stick to a couple of safety precautions.
All right, let’s get started then.
Cool! I will skip over how to install GnuPG for your particular operating system today, since there are lots of guides available on the Internet. Something I haven’t found on the Internet, however, is a good guide for beginners to GnuPG.
We will assume you have GnuPG already installed.
A word of warning
If you believe you are being targeted by state actors or other government-level, megacorporation-like entities, do keep in mind this comic from XKCD:
Wait, which version of GnuPG?
This guide is written with GnuPG 2, however I’m pretty sure most of the commands still apply to GnuPG 1. GnuPG 1 is still in use on a lot of servers and other computers where low-footprint is a priority. For more details on the differences, check out this SuperUser answer.
If you are using GPG 2, on some distributions and operating systems, you might need to change the commands below to
gpg2 instead of
gpg. Otherwise, all of the other parts of the command should be exactly the same.
Creating a key
To create a key, run:
If that command does not guide you through the interactive process: selecting key size, key type, and what not – then run:
You should see the following:
Press Enter. RSA and RSA is fine.
For keysize, I recommend 4096 bits. Since we’ll, for the most part, be using GnuPG for sensitive things, a longer encryption/decryption/signing/verifying time will be worth the wait. Type
4096 and then Enter. Note that you may want a smaller keysize if you are going to use GPG on, say, mobile devices, where computing power may be limited.
Now, the best practice is to set a expiration date for your key. But GnuPG also has another feature else in case you don’t want to repeat this key generation process every couple of years: creating subkeys, where you just create more and more keys with your “master” key. We’ll go more into subkeys below, but for now you can just leave it to never expire. Press Enter.
GnuPG warns us that the key won’t expire. Type
y, and then Enter.
This part should be easy. Just fill out your information, like so:
o, and then Enter. (If you want to change anything, just type the letter in parentheses for the field you want to change, and then press Enter!)
GPG should now prompt you for the passphrase. Type it in, then press Enter. You will need to do this twice. This will be the safeguard against anyone breaching your computer and taking the key. They won’t be able to use the key without the passphrase. (This does NOT mean, however, that you should not revoke your key. If you notice your key has been compromised, revoke the key immediately.)
Then GPG should start the process of generating your public/private key pair. This warning should come up:
If you have a slow computer, now’s your chance to fire up a copy of Minesweeper and start playing. But if your computer is fairly modern and fast, this process should only take 30 seconds or so. Just shake your mouse around until the terminal prompt changes to this:
Congratulations! You created your first GPG key.
Listing available keys
To see your available keys, run:
This should print something like:
Note that some distributions and operating systems may not show the key ID in full. To see the correct output, run this:
You can also use
short, if you have a small number of keys and don’t want to type out the entire UUID!
Publishing your key
To give your key to others, you must first publish your key.
First, you need to find your public key ID. To do this, run the command from “Listing available keys.” In the output, find this line:
rsa4096/ should be different for you. That,
56F399E7A57D6E5D, is your public key ID.
Then send it off to the keyserver!
Following the syntax above, I would run:
Receiving published keys
If you followed the steps above to publish your public keys, then it should be simple for others to retrieve your keys and start using them to encrypt data for your eyes or verify something is actually made by you.
Publish your key ID somewhere, maybe in a blog (hint, hint). Then others can just download your key using this command:
So for people to get my key ID (note that this is NOT my actual key, it’s just for this tutorial, look at my GPG page for the actual public key), they can just run:
If GPG throws an error, it could be that the key is not available. Search for the key:
Using custom keyservers
If you just run
gpg --send-keys or
gpg --recv-keys without any other parameters, GnuPG usually uses the default keyserver, which is at
hkps://hkps.pool.sks-keyservers.net. You can see that this URL is a bit unique: rather than
https, it now reads
hkps is what GnuPG uses for the keyserver locations.
For example, when I had to verify my Manjaro .iso, I had to download the keyfiles of Philip Müller, the project leader, from a different keyserver. Their wiki gives the address of:
So to use a custom keyserver, just specify it as a parameter:
So, to fetch Philip Müller’s key, I had to run:
Note that the
--keyserver parameter must be typed before the other parameters.
Creating a revocation certificate
This step is needed for when you accidentally expose your private key. Maybe you accidentally sent the wrong key file when sending your public key to your friend (this is why we use keyservers, like shown above)
Execute the following command:
So for me, it would be:
That command will produce something like the following output:
y and then Enter to confirm.
Press Enter to accept defaults, unless you have a specific reason behind the revocation.
This part is optional. Continue by pressing Enter.
y and then Enter to confirm.
GPG will then ask you for your passcode to sign this revocation certificate with your private key. Type in your passcode, and then press Enter.
Fun fact: Mallory is an alias the GPG community gave for “bad actors”. The more you know! Also, if you are confused about the term “ASCII armored output”, check out this section explaining the differences between regular GPG files and ASCII-armored GPG files.
Finally, save the revocation certificate somewhere safe. This can be used to completely wipe out your key pair and render it useless, as the message warns above. Some paranoid people even print the ASCII-armored output and when it’s time to use them, they utilize OCR software to read the printout! But that’s probably overkill.
Hopefully you won’t ever need to use this…
Revoking the key
Get the certificate you generated in the section above. What? You decided to be paranoid and printed it out? Fine, fire up that OCR software. Go ahead, I’ll wait.
Have the certificate in text format, on your computer? Good. Let’s locally revoke your key first.
So I would run:
Then follow the steps in “Publishing your key” again to update the public key in the keyserver and let others know your key has been compromised. Note that once the changes have been published, you will not be able to stop the revocation locally.
Stop revoking the key!
“Wait, I don’t think my key was exposed! Can I go back?” Sure you can, if you meet the following prerequisites:
- The key has only been revoked locally
- The public key has been published before to a keyserver, prior to revocation
Let’s make GPG forget that you requested the revocation:
For me it would be:
--expert parameter allows you to delete the public key only.
y, and then Enter to confirm.
Now we need to download the clean public key from the keyserver, that hasn’t been marked as revoked. Follow the steps from “Receiving published keys” for this process.
Alternatively, you could also import a local copy of the public key, if you had a backup available with the key not being marked as revoked.
Importing keys is also crucial. You will use it all the time to get keys from other sources (in case you don’t trust keyservers).
Fortunately, this process is fairly simple. You just need a GPG file, or an ASCII-armored GPG file. They usually have the following extensions:
Run the following command:
What is ASCII-armored?
ASCII-armored basically means it’s in text form and not in a binary format. This makes it useful, for example, when you’re sending the file over email.
Usually, you can force ASCII-armored by appending the parameter
--armor to your command - this will ensure your file is editable via text editor (not that you would ever want to edit something outputted by GPG).
This is also part of the key management process. Don’t worry, we’re getting to the fun part of actually encrypting, decrypting, and certifying data, but this part may actually be more fun to you.
Do you know how you get the padlock on your browser, next to that URL? That reassuring green padlock is letting you know that the site you’re visiting is actually the site you want, and that the contents are encrypted in transit.
To do this, the site owner must get an SSL certificate from a root authority, such as Let’s Encrypt, Comodo, DigiCert, and so on. Out of these providers, Let’s Encrypt is the only one that does this for free, but the reason they can provide it for free is that they are a) sponsored by a lot of charitable organizations, and b) because the signing window is small (i.e. you can only have it signed for like 3 months or so.) Also, Let’s Encrypt relies on an automated way of verifying websites, saving costs.
So why are the rest of those providers asking for money for SSL certificates? Well, every time they give out the SSL certificates, the providers need to make sure that they’re giving the certificates to the actual owners of the website, and not some bogus bad actor (Mallory). Bad stuff can happen if they mess this up, and it has definitely happened in the past. When this happens, browser makers typically revoke the trust for that specific root authority, so they have a lot of incentive to not mess this up.
Of course, there’s that entire issue of governments spying on their citizens by installing rogue root authorities, but that’s not in the scope of this article. What I’m trying to point out here is that this model is horrible. It’s horrible because you’re relying on that one central authority to be the “good guys” and not create certificates for people that don’t deserve them.
To counter this, a different model that GPG uses is the “web of trust”. You’ll see why it’s called a web in a moment. Let’s say I have a friend, A. I trust that guy because A’s a solid dude, so when A comes and asks if I can sign A’s key, I say “sure!” I know that A is A, because I’ve met A in person, and I know that the key A gave me is A’s key, because A physically presented it to me.
Later, A meets B, a close friend of A but a complete stranger to me. B asks A if A can sign his key. Because A trusts B, A does the same, and signs B’s key. Now, A suggests to me that I should host a party with B. Since I don’t know B, I need to share contact information with B. I go to B’s website and find B’s public key. Now I know I can trust B, because B is trusted by A, and I trust A.
This model works wonders because the more keys you sign, the more keys they sign, the higher this level of confidence that the keys belong to the right person. This is why it’s called a web of trust. When put together, the entire system looks like a web:
People even host real-life parties to sign keys! Of course, that doesn’t mean you should just sign any random stranger’s key… You should always verify their identity!
The process is simple - you note down your public key ID on paper (you usually do not bring your computer containing your key pair since that can increase the chances of your private key being leaked) and attend a key signing party. During the event, you write down as many public key IDs as you can, provided that you have verified each individual’s identity first. Afterwards, you come home, you receive the keys, and then you sign them:
And then you publish them again to reflect that you trust the key. (Note that you should publish their public key, NOT your public key.) Warning: if their key was not published in the first place, publishing them may be rude, so you should always ask for the key-owner’s permission.
For example, if I wanted to sign that Manjaro developer’s key, I would type:
This would result in the following output:
y, and then Enter. GPG will ask you for your password. Type it, then press Enter to sign the key.
Remember that you may also need to update their “trust level”. (Down below)
Key signing party guide
- Do not bring your computer. This increases the chances of your computer getting infected with key-stealing malware, or you accidentally misplacing your private key. Just publish your public key, jot down your public key ID somewhere, and then bring that to the event.
- For friends, just sign their keys. For strangers (like if you are at an international event or something), verify their identity with something like their passport, and make sure their identification papers are not forged.
- You can always batch-sign keys after the key signing event. Weird, right? Yeah, the actual key signing happens after the event.
What is trust?
Trust, in GnuPG, is this mental note you put down in your own keyring, noting down how “trustworthy” an individual is.
Let’s say I have this great friend who is also a nerd. This friend will only sign responsibly, and actually verify all identities before signing. I’ll give this friend a higher trust value because I believe that this friend will make good decisions.
Compare that to a code signing event, where I’m signing the keys of complete strangers. I don’t even know if they’re responsible or not - I’ve only just met them! Therefore, when I sign their key, I assign them a trust value of unknown, or 1.
Note that if you sign someone’s key, their default trust value will be 1 - or unknown. This is usually what you want, unless you really trust the individual to make good decisions.
To edit someone’s trust value, use this command:
trust, and Enter to edit their trust value. Press Enter to save the trust value, and then type
quit to exit the application.
Backing up your keys
If you lose your key pair, horrible things can happen. And these events are all too common. Dead hard drive, lost USB, computer blows up, et cetera. Let’s prevent a catastrophe!
If you want to be lazy, just back up the entire
.gnupg directory. There you go, keep that safe. But if you want a more thorough approach, run:
This should save your secret key to the file
KEY_ID_SECRET.asc. Back it up somewhere safe.
For added convenience, also back up your public key. This is not strictly required, but deriving the public key from the private key is annoying:
Note that if you ever re-import your keys, you may have to set their trust level to 5 again to let GPG know that the keys are yours.
Subkeys are basically smaller keys made from your master key file. You can play a bit loose with them, because even if they get exposed you can easily revoke them with your master key.
Run the following command to edit your master key:
This will result in the following output:
Let’s add a key using
You probably need two subkeys: one for signing, and one for encrypting. There’s already a subkey for encrypting, so for now, I’ll show how to create a signing subkey. Type
4 and then press Enter:
Remember this, right?
4096 all the way! Press Enter after typing that.
Enter again, key does not expire (again, you can just revoke them if you lose them). If you need a temporary key that needs to expire, use the syntax above to set a time limit for them. For example, if you want them to expire after 3 months, then type
3m. But for now, I’ll accept the defaults:
y, and then Enter.
y again, and then Enter. It should ask you for your passphrase, and then warn you about entropy, and then create that beautiful subkey:
You can see the subkey right there, with the ID
CFE50DE6144F5CA0! Now we need to save the changes. Type
save, and then Enter.
To export the key and use it somewhere else, type:
The exclamation mark is extremely important. Without it, you will be exporting ALL of the subkeys, which might not be what you want (for example, you wouldn’t want to export your decryption subkey to a sensitive computer!)
Then on the target computer, type:
To import the subkey! If you want to revoke it at any time, just edit your master key again, and then type
revkey. Finally, publish your changes to the keyserver.
To delete your main keyring, run:
Note that this also removes your keyring (be careful!)
Keeping keys updated
Keys constantly change. People may sign keys, revoke them, or even generate new ones! So to keep your keyring up-to-date, it’s a good idea to run this periodically:
This also updates your public key, if you’ve published them on a keyserver.
Now pat yourself on the back if you’ve come this far, as we will now get into how to actually utilize those keys!
You need the other person’s public key for this. Type the following command:
GPG will prompt you to enter the user ID. Enter their name if their name is unique in your keyring, or their public key ID.
You can also specify it with the parameters:
Remember, you can ASCII-armor your GPG file here!
This one is easy, since your private key file is already there. Run the following command:
Or .asc, if the file is ASCII-armored.
Depending on how you want to sign a file, there are a couple of options. If you want to make a compressed, signed file, run the following command:
This command will create either
file.tar.gz.asc, depending on whether or not you supplied the
When you send your recipient the file, you just need to send them the
file.tar.gz.asc file. They can verify it using the command below, and decrypt (unpack) it using the command above, without the need for your private key. (This is because the file is merely compressed and signed - it’s not encrypted with your public key.)
However, this method has problems. What if you are sending an email, and want your recipient to be able to read it immediately, without decrypting the file?
Well, you can send your recipient a cleartext file signed with your key:
This is used when you’re sending plaintext documents, like emails. The plaintext message is first shown, and the signature follows shortly after.
That’s great and all, but what about big files? You don’t want to necessarily create another file for the signature that will take up just as much as the original file! This is where “detached” signature files come in. Most Linux distributions and other big library/framework projects use this method for distribution. You create a detached signature using this command:
“Wait,” you say. “What’s the difference between this and the first command?”
The first command compresses the entire file, signs it, and then spits out a GPG file based off of that. This means that transport becomes easier, because the signature and the file becomes one file. However, the method requires you to pack the file and spend resources making a new file, and the method requires the recipient to use as much resources to unpack the signature file to get the original file.
However, this “detach” command creates a signature file that is only a couple of kilobytes in size. This in turn is used to verify the original file. This is what you see when you see files on Linux distribution websites - “Ubuntu.iso” and “Ubuntu.iso.sig” or “Ubuntu.iso.asc”. The latter two verifies the first file, and they are only a couple of kilobytes in size.
In comparison, if you used the first command to generate the signature, GPG will actually warn you that the signature is NOT a detached signature, and therefore GPG has no way of verifying the original file. You will have to unpack the signed file and then compare checksums between the two file to make sure they are not tampered with. But at that point you don’t need to download the original file. This is why the first command should be reserved for files of small size.
TL;DR - Clearsign for emails and plaintext files, detach for big files (like .isos), and finally compress and sign for regular files (couple of megabytes).
Thanks for following along on this huge, massive, overly complicated article! I hope you learned a thing or two about GPG and keys and signing and encryption.
Encrypted here means encrypted in-transit. Think of it as Gmail using HTTPS to encrypt it while the data is flowing from your computer to Google’s servers. It does not mean the email is encrypted at-rest, as in not even Google can read your emails if they are not the intended recipient. ↩