An Introduction To PGP
Corbin Taylor
Posted on January 16, 2022
I am someone who has been interested in privacy and security for most of my adult life. I am also someone who can be described as, perhaps, a tiny bit paranoid at times. Are these things related? Probably.
However, you do not have to be paranoid to want to be secure and to have your privacy maintained online. Even if you don't have something to hide, that doesn't mean that your friends don't.
What if you're talking to someone who is standing up for women's rights or is LGBTQ+ in a country where such things are socially (or even legally) dangerous? If you don't keep yourself secure, then you could become their vulnerability.
I'm not trying to scare you, and I'm certainly not trying to turn you into some conspiracy theorist. I'm just trying to point out that, even if you have nothing to hide, that you should be conscious of your online security posture.
So, you may ask now, what should I do about it?
There are many good security and privacy tools and services out there (which I may expand upon in a future post), but today I want to talk about something that I have been playing around with recently: PGP.
What Is PGP?
PGP (short for "Pretty Good Privacy") is an protocol used to encrypt, decrypt, and sign data. It's widely used, and if properly implemented, is considered a great way to protect yourself and your private discussions online.
The idea behind this is that, you will start with a public and a private key that are paired. The public key is something that you can share openly with people, while the private key you should keep hidden.
The public key allows others to mark you as the recipient of a document, encrypting it and saying that only you can decrypt it.
The private key allows you to confirm who you say you are, and decrypt the message that was sent to you.
Furthermore, say you want to send a message to someone, and you want to make sure that they know you are who you say you are. PGP allows you to sign the document using your private key which the other person can confirm you are who you say you are by comparing it to your public key.
If you want a high-level description in video form, Computerphile has nice video here.
Where Do You Get PGP?
The modern incarnation of this protocol, OpenPGP, was implemented by the Free Software Foundation in GPG ("GnuPG" or "GNU Privacy Guard"). If you are on Mac OS X, the easiest way for you to get GPG is through GPG Tools.
How Do You Use PGP/GPG?
Now that we have gone over "what" PGP and GPG are, I want to go over some of the basic usage.
This tutorial will only really scratch the surface, but I hope that I can at least teach you some things that can help you keep private things private.
Some Notes Before We Begin
For the rest of this article, I am going to assume that you have installed GPG, which as explained has implemented implemented OpenPGP. I will be showing you examples via the terminal.
In my case, I am a Mac OS X user and I will be showing examples via my preferred terminal, iTerm2 that uses zsh that has been customized with Oh My Zsh. My Oh My Zsh theme is af-magic with the synthwave-everything iTerm2 theme.
If you want to know more about terminal customization, comment below or reach out to me on my Twitter.
Getting Into The Terminal And Verifying Installation
To start with, you will need your terminal open and GPG installed (see above).
Once you have your terminal open, you can confirm that you have GPG installed by doing the which gpg
command that shows the file path.
The first, and incredibly useful command to know is gpg --help
which is gives you a list of the available commands and the various flags associated with them. It's especially handy if you ever forget something (which I do all the time).
Creating Your First Public/Private Key Pair
Once you have made sure that you can use GPG and have taken some time to read some of the help document, it's time to generate your first key pair.
Run the command gpg --full-generate-key
, and you will be prompted about which algorithm you wish to use to generate your public and private keys, as well as the number of bits of information (or entropy that they will contain.
A theoretical discussion of what this all means is well beyond the scope of this blog post, but practically speaking, you can think of entropy being associated with the chance that a hostile actor could break the encryption via brute force repetition. The more bits, the harder it is for them to break the encryption.
In this case, I have chosen (1) RSA and RSA
and 4096
bits.
After choosing the algorithm, you will then be prompted about the expiration date of your key-pair. You can choose a range from days to years (e.g., 2y
), or to not have an expiration date at all (i.e., 0
).
After that, you will be asked to generate a UID for the key, which is a combination of your name, your email that you want associated with the key, and some optional comment. This metadata will be a way of telling others who you are claiming to be.
In this case, I wrote my name (Corbin), the email (cjtaylor1990@dev.to), and my comment is something unquestionably true, which is that I love coffee and cats.
Finally, you will be prompted to give a pin to be associated with the private key. Any time you try to use the private key, you will be asked for the key pin.
For my case, I used a 40 character string that I randomly generated using 1Password. Alternatively, if you don't have a way to generate and store passwords electronically, you could use diceware to generate passwords and then store it on a piece of paper in your wallet or a safe.
After giving the pin code, gpg
will generate the key pair and will give you a confirmation, as well as importing the public and private keys into your GPG key ring to be used later. The GPG key ring is simply the way that GPG stores and manages PGP keys on your local machine.
Notice in the picture above that there is a long alphanumeric string (212CF1042D88FFF461A62B76811A3B169B7EA4B7
) above the uid
. This is a unique identifier known as the key fingerprint and the last 8 values in the string, 9B7EA4B7
is the key ID.
To confirm that you now have the key in your key ring, you can use gpg --list-keys
. You can list the specific key that you just generated by specifying the email, the key ID, or the finger print values as arguments. Alternatively, you can just use the command as is to list all of the keys that are listed on your key ring.
How To Encrypt A File That Is For Your Eyes Only
Now that you have a public/private key pair, you can actually start to do basic encryption/decryption. For example, say that you have a message that is for your eyes only. We could put that into a text file and encrypt it using the key that you just created.
First, you will need such a file. An easy way to create such a text file would be to use the echo
command and then send it to an output file (e.g., test.txt
) using the output operator (>
).
For example, echo Hello, PGP! > test.txt
. This will generate a test.txt
file with your secret phrase, Hello, PGP!
inside of it.
You can then confirm that the file contains the message using the cat
command.
). This will output a text file at the path specified (e.g., test.txt) with the output inside of it. You can see what's inside of the file using the cat command. In this case, we see that you find "Hello, PGP!" inside of the file."/>
Now that you have your text file with your super secret hidden message, you can then encrypt it using gpg --encrypt
and specifying yourself as the recipient with the --recipient
flag.
In this case, that would be gpg --encrypt --recipient cjtaylor1990@dev.to test.txt
. This will output an encrypted file, test.txt.gpg
which you can check the contents of with cat
.
If you see a garbled mess, then CONGRATULATIONS! You have created an encrypted message, and if you cannot currently read it, then hackers (or the NSA) likely can't easily read it either.
Now, if all we could do is encrypt the message, then that's not very useful. You want to come back later and decrypt the message!
You see, by encrypting this file this way, we have used your public key (the one that you can give to others) to encrypt a message specifies that only the real you can decrypt.
Thankfully, this is where the private key comes in! This also shows why it is VERY important not to share your private key with others.
Your private key (protected by your key pin) is the means by which you prove that you are the owner of the public key. The real you.
Since you have the private key on your GPG key chain, all you would have to do is use gpg --decrypt
on the encrypted file, and it will then print the secret message to the screen along with the recipient (you). Note that you will be prompted (via popup) for your key pin before your private key can be used.
Furthermore, you can use the output (>
) operation to put the secret message into a file that you specify.
For example:
gpg --decrypt test.txt.gpg > test.txt.clear
where I have chose the '.clear' file suffix to represent a clear-text file (as compared to an encrypted file).
Importing A Friends Public Key To Your Key Chain
Now, encrypting messages to yourself is nice, but what if you could encrypt messages to others? Well, you can! But first, we need another friend that uses PGP.
Let's say my awesome friend @pachicodes has decided to send me their public key. Likely, it would be something like public.pachicodes@dev.to.asc
, where the .asc
is an "ASCII armored" file type that is often used to store and exchange PGP keys. While the raw PGP key is a binary file, the .asc
file is an ASCII representation of that binary.
Once Pachi has given me the public key, I can import the public key into my GPG key ring using gpg --import
, specifying the file as an argument.
Encrypting A Message To A Friend
Now that I have my friend Pachi's public key, say that I now have a secret message (stored in for_pachi.txt
) that want to send them. I want to make sure that only they can read it.
I can use their key to designate them in the --recipient
flag in gpg --encrypt
. Furthermore, to tell Pachi that the message is really from me by signing the encrypted file.
In full, to encrypt the for_pachi.txt
file, we would do,
gpg --encrypt --sign --local-user cjtaylor1990@dev.to --recipient pachicodes@dev.to for_pachi.txt
where --sign --local-user
allows gpg
that I want to sign using one of my local keys, cjtaylor1990@dev.to
. Again, this will produce an encrypted .gpg
file.
This signing is done using the private key that you generated earlier, and GPG will once again prompt you to give a key pin. If I had given the part of my key that I can share (my public key) to Pachi earlier, GPG can compare the public key against the private key signature on the encrypted file and confirming that it was actually me who signed and encrypted it.
Assuming that Pachi has my key imported into her own GPG key ring, she can decrypt the encrypted file, see that it was from me, and what the secret message is:
Now Pachi and I have successfully exchanged public keys, and using our secret private keys, we have successfully exchanged encrypted messages back and forth to one another. Only those with access to our private keys (and key pins) could successfully sign the encrypted messages, or decrypt them to read. In this case, Pachi sees me exclaim that "We are awesome hackers!"
This idea is the heart of PGP encryption, and what makes it so powerful as a privacy and security tool. It's used in many popular privacy-focused software, such as Proton Mail and Signal as a means of strong end-to-end encryption, and has famously been used to journalistic sources and whistleblowers.
Even if anyone was able to get a hold of the traffic being sent between Pachi and myself, they would not be able to decrypt it to know what it meant, not even the service we were using to communicate!
PGP Exporting, Back-Up, And Publishing
You can export both your public and private keys as .asc
files by using the gpg --export
and gpg --export-secret-keys
, while also specifying the key you wish to export and using the output operator (>
) to specify the file name.
For cjtaylor1990@dev.to
, we can export the key pair by doing:
gpg --export --armor cjtaylor1990@dev.to > public.cjtaylor1990@dev.to.asc
and,
gpg --export-secret-keys --armor cjtaylor1990@dev.to > private.cjtaylor1990@dev.to.asc
The --armor
flag specifies that we want gpg
to output everything armored ASCII format instead of a binary.
Now that both parts of the key pair have been exported from GPG, you can then back them up (e.g., on an encrypted drive). Backing up your keys is important, as without them, you will be able to decrypt any message intended for you nor sign any encrypted file.
Finally, you can share your PUBLIC key by uploading it to a public key server that allows other to download it and import it so that they can contact you securely.
To do this, you can use the pgp --send-keys
command, specifying the key-ID (in my case, 9B7EA4B7
or the last 8 characters of my key fingerprint).
The default server is key.openpgp.org, which you can then search using your key's fingerprint.
Revoking A Compromised Key
As this whole protocol is dependent upon on each person keeping their private key uncompromised, it is important to make sure that you revoke a key that you believe to be compromised. You can likewise revoke a key if you no longer use it.
To make sure you are ready for such a scenario, you can generate a revocation certificate for your key using the gpg --gen-revoke
followed by your key ID. You will then use the output operator (>
) to output the data to a file, in this case revoke.cjtaylor1990@devo.to.asc
. You will then be asked for more details about why you are revoking the key.
You can then keep the revoke certificate .asc
file around for safe keeping (DO NOT SHARE IT) and if you find that you have to mark it as no longer a valid key, you can then import the certificate as a key into your GPG keychain. This will mark the key as revoked and no longer valid.
You can confirmed that the key was revoked using gpg --list-keys
and then send the updated (revoked) public key to the public key server using gpg --send-keys
.
Keeping a revoke certificate around and making sure that any compromised or unused key pairs are marked as revoked helps protect you from others reading any encrypted data with you as the recipient. Furthermore, it makes sure that others can trust that any information signed by your private key is really from you.
Deleting PGP Keys From Key Ring
If you have revoked a PGP key pair and no longer need it, you can delete it from your local key ring.
First, start by deleting the private key by using gpg --delete-secret-keys
and specifying the key that you wish to delete. In this case, I am deleting the secret key associated with cjtaylor1990@dev.to
that I revoked in the last section.
You are then able to delete the public key with gpg --delete-key
, while specifying the key in the same fashion as you did in the previous command.
Summary And Final Thoughts
If you've been following along, you now have created your own PGP key pair (a public key and a private key) using gpg --full-generate-key
. The public key can be shared with others, while the private key and your key pin should be kept secret.
With your public key, you encrypted a secret message using gpg --encrypt
that only the person with your private key (the real you) can decrypt; you specified who can open it using the --recipient
flag.
With gpg --decrypt
and your key pin, you decrypted your secret message, confirming that it is the same one that you started with despite having been garbled and made a mess of during the encryption process.
Similarly, after importing a friends PGP public key, you were able to import it into your GPG key chain using gpg --import
and then encrypt a file addressed to them using similar commands, but adding the --sign --local-user
flags to sign the encrypted file with your private key and allowing your friend to know it was from you.
You learned how to export your public and private keys using gpg --export
and gpg --export-secret-keys
respectively as a way of backing them up. You also learned how share your public key via a PGP public key server using gpg --send-keys
.
Finally, you learned how to generate a revoke certificate using gpg --gen-revoke
so that, if your keys are compromised, you can invalidate them locally (by using gpg --import
to import the revoke certificate) and on the PGP public key server (by using gpg --send-keys
after the key has been marked invalid locally).
While this introduction does not necessarily cover all there is to know about PGP, nor does it cover specific use cases (e.g., email encryption) or how to use the GPG Tools GUI, I hope I was able to help you appreciate (or even want to use) this useful privacy tool.
I would not consider using PGP the first thing you should worry about when improving your online security posture; that would probably be to use a password manager and enabling two-factor authentication. However, I still consider it very interesting and an incredible privacy tool, with an excellent track record.
Thank you for reading this introductory tutorial on PGP encryption. I know it's been a while since I wrote anything, but this has been an interest of mine lately, and I wanted to share.
Posted on January 16, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.