What is PGP?
Pretty Good Privacy, that’s what PGP stands for. It’s a pretty basic description for an encryption standard that’s been in place since the 1990s and one that’s been steadily improved upon over the years to remain the most widely used encryption standard.
PGP is a workhorse, used to encrypt emailed sensitive data or files before they leave on their way to your trading partners or remote locales. It uses a variety of encryption technologies including public/private PGP keys, data compression, hashing, and more. It also is the backbone of offshoots such as Open PGP and GPG.
What is GPG?
GNU Privacy Guard (GPG), sometimes referred to as GnuPG, is simply a different implementation of the Open PGP encryption standard as defined by RFC 4880, the official name of the Open PGP standard.
It uses the concept of Asymmetric encryption:
- In
Symmetric encryption
, there is only one key, generally known as password, which we use to encrypt/decrypt the files. Now the problem here is, how will you share the same password over the network to the sender/receiver. This problem is solved in Asymmetric Encryption. Le’s see how. - In
Asymmetric encryption
, there is a pair of keys, one public and one private. The owner can share the public key with anyone whosoever wants to send the files in an encrypted format. That encrypted file is then sent back to the owner and that can only be decrypted by the corresponding private key.
The difference between PGP and GPG
PGP is the basis or structure that stands behind Open PGP. Open PGP is a non-proprietary protocol, whereas PGP is a proprietary solution owned by Symantec. Open PGP uses public key or asymmetric cryptography and can be applied to features, tools, or more fleshed out solutions that support open-source PGP encryption technology. Open PGP also addresses the issues of data authentication and non-repudiation with the ability to “sign” files via embedded digital signatures.
GPG Use Cases
Encryption
: Used to encrypt files. We can some content to someone and you don’t want anyone in the middle to read it.Signing Commits
: Helpful for proving your identity. For eg, you can use this GPG key to sign your commits in Github, to basically verify that you’re the one actually done it.Encrypting Passwords
: Very helpful if you use a command line password utility like a password manager called pass. It uses your GPG keys to handle the encryption for all your secrets you want to store in that password manager.
Key management
When it comes to keys there are private(secret) keys and public keys. They are paired together. The public key is, as expected, something you can make public and share with others. The private key is like your secret password though, don’t share that one with anyone! You might have the public key of many people stored on your computer but the only private key you will probably have is your own.
-
List keys stored locally
# List public keys you have stored (yours and other people's keys)
gpg --list-keys
# List private keys (generally only your own)
gpg --list-secret-keys
-
Create a new private key
Use the –gen-key flag to create a new secret (private) key. This will walk you through an interactive prompt to fill out the questions like what is your name.
gpg --gen-key
This will take you through a few questions that will configure your keys:
* Please select what kind of key you want: (1) RSA and RSA (default)
* What keysize do you want? 4096
* Key is valid for? 1y (expires after 1 year. If you are just testing, you may want to create a short-lived key the first time by using a number like “3” instead.)
* Is this correct? y
* Real name: your real name here
* Email address: your_email@address.com
* Comment: Optional comment that will be visible in your signature
* Change (N)ame, ©omment, (E)mail or (O)kay/(Q)uit? O
* Enter passphrase: Enter a secure passphrase here (upper & lower case, digits, symbols)
At this point, gpg will generate the keys using entropy. Entropy describes the amount of unpredictability and nondeterminism that exists in a system. GPG needs this entropy to generate a secure set of keys.
-
Export a private key
You might want to export your private key in order to back it up somewhere. Don’t share your private key with other people though. You can export in armored (ASCII) format and you could actually print it out on paper or write it down since it is human readable and put it in cold storage. Text format may also work better than binary in certain communication mediums.
# Find the ID of your key first
# The ID is the hexadecimal number
gpg --list-secret-keys
# This is your private key keep it secret!
# Replace XXXXXXXX with your hexadecimal key ID
gpg --export-secret-keys --armor XXXXXXXX > ./my-priv-gpg-key.asc
# Omitting the --armor flag will give you binary output instead of ASCII
# which would result in a slightly smaller file but the ASCII
# formatted (armored) can be printed physically, is human readable,
# and transfered digitally easier.
# Both formats can be imported back in to GPG later
-
Delete a key
You can delete a private key from local storage with the following command:
# Private keys
# Use the ID listed with --list-secret-keys
gpg --delete-secret-keys XXXXXXXX
# Public keys
# Use the ID listed with --list-keys
gpg --delete-keys XXXXXXXX
-
Import a key
If you need to import a key you can use the following command. This is useful if you are on a new computer or a fresh install and you need to import your key from a backup. You can import a public or a private key this way. Typically the only time you will be importing a private key is when restoring a backup of your own private key. The most common case for importing a public key is to store someone else’s public key in order to send them a private message or to verify a signature of theirs.
# This works the same for binary or ASCII (armored) versions of keys
# This is also the same for private and public keys
gpg --import ./my-priv-gpg-key.asc
# You can also directly import a key from a server
# For example, import the DevDungeon/NanoDano public GPG key from MIT
gpg --keyserver pgp.mit.edu --recv C104CDF0EDA54C82
-
Create a Revocation Certificate
You need to have a way of invalidating your key pair in case there is a security breach or in case you lose your secret key.
gpg --output ~/revocation.crt --gen-revoke your_email@address.com
-
Push your public key to key server
You may want or need to publish your public key somewhere where everyone can find it. For example, to push code to the Maven central repository, you must sign your code with a GPG key that has a public signature somewhere like the MIT public key server. You can push your public key using the –send-keys flag.
# There are many public key servers out there, not just MIT
# Replace XXXXXXXX with your key id from --list-keys
gpg --keyserver hkp://pgp.mit.edu --send-keys XXXXXXXX
Encryption
There are two types. Symmetric and asymmetric. GPG supports many different algorithms for each method. The most commonly known ones are AES for symmetric and RSA for asymmetric. ECDSA is starting to slowly replace RSA though. The following examples will demonstrate how to do both symmetric and asymmetric encryption as well as decrypt a message.
-
Encrypt with a passphrase (Symmetric)
Can be decrypted by anyone with the passphrase. No specific recipient. Passphrase can be shared with many people. This can be useful for just encrypting files locally with a simple passphrase, or to encrypt a document before sending it to someone. You’ll have to find another channel to send them the passphrase though if it is not already exchanged before-hand.
There are two formats of output you can get: binary and text. The binary version will take up less space, but the ASCII version is a little easier to work with and can be transported over text means, say, pasted in to an email. They both decrypt the same way.
gpg --symmetric message.txt
# Prompts you for a passphrase
# Creates message.txt.gpg (binary)
gpg --armor --symmetric message.txt
# Same, but ASCII format output instead of binary
# Creates message.txt.asc (ASCII)
# Specify the encryption algorithm
gpg --symmetric --cipher-algo AES256
# Get the list of cipher algorithms
gpg --version
# E.g. 3DES, BLOWFISH, AES256, TWOFISH
# Specify output file
gpg --output message.txt.gpg --symmeteric message.txt
# Encrypt and sign (all in the single output file)
gpg --sign --symmetric message.txt
-
Encrypt for a single recipient (Asymmetric)
You can encrypt a message for a single specific recipient. You do this by encrypting asymmetrically with your private key and the recipients public key. By doing this, only the recipient’s private key will decrypt the message. You will need the recipient’s public key in order to do this. They can share their public key with you directly, or you can search public key servers.
# Import NanoDano's public GPG key
gpg --keyserver pgp.mit.edu --search-keys nanodano@devdungeon.com
# It will print a list of matching results.
# Enter the number next to the one you want to import
# After it's imported you can verify the public key is stored with
gpg --list-keys
After you have the receipient’s public key imported, you can encrypt messages that only they can decrypt.
# This will prompt and ask the recipient's email address
# and you will have to enter the ID or email
gpg --encrypt message.txt
# or specify the recipient as the -r argument
gpg --recipient nanodano@devdungeon.com --encrypt message.txt
# Encrypted output will be in message.txt.gpg
# Encrypt and store in ASCII format (message.txt.asc)
# Both binary and ASCII versions decrypt the same
gpg --armor --recipient nanodano@devdungeon.com --encrypt message.txt
# Encrypt and sign at the same time
gpg --encrypt --sign --recipient nanodano@devdungeon.com message.txt
# Specify output file
gpg --output message.txt.gpg
-
Decrypt a message
You can decrypt messages with the -d or –decrypt option. It will automatically determine if it is symmetrically encrypted with something like AES and it needs a passphrase, or if it was encrypted asymmetrically with something like RSA and it needs to look for a private key. The recipient will be detected automatically and GPG will search locally to see if the private key is stored. If it is, it will ask for the passphrase and then print out the decrypted message to the console. If it is a symmetric encryption it will prompt you for the passphrase, and then print the message.
# Decrypt and print message to screen
# Will automatically verify signature if there was one
# Will automatically detect if symmetric or asymmetric
# Will automatically use the appropriate private key if available
# Will automatically prompt for passphrase if symmetric
gpg -d message.txt.gpg
# Decrypt and put output in decrypted.txt
gpg --decrypt message.txt.gpg > decrypted.txt
Signatures
You can sign files that were encrypted using asymmetric or symmetric methods. The benefit of providing a signature is to let everyone prove that you were the author of the file, or at least, you confirmed the contents of the file at the time of your signature. You can also just sign files without encrypting them at all.
-
Sign a message
You can use the sign feature without any encryption. That is, if you want to share something in plain-text or make a public post that everyone can read, but you want to include a signature to prove you were the original author.
The resulting output file is the unencrypted original document with a signature at the end. It is not used to encrypt and secure the information and guarantees no confidentiality. It only proves integity and authenticity of the message. You can create a binary signature or a plain-text signature.
gpg --clearsign message.txt
# Outputs message.txt.asc in plain text, suitable
# for pasting in an email or posting online
gpg --sign message.txt
# Outputs message.txt.gpg a binary file
# Both of these can be verified with --decrypt
# but they are not _actually_ encrypted.
gpg --decrypt message.txt.gpg
gpg --decrypt message.txt.asc
# This will print out the message along with the signature info
-
Encrypt and sign
You can encrypy-and-sign a message in one step. This will attach the signatures to the encrypted file. With these two encrypt-and-sign methods below, the signature is included in the encrypted .gpg/.asc file that is output. When someone decrypts them, the signature will be checked automatically.
# Symmetric encrypt with signature
gpg --sign --symmetric message.txt
# Asymmetric encrypt with signature
gpg --sign --encrypt --recipient nanodano@devdungeon.com message.txt
-
Verify signatures
If a signature is included in the encrypted file, GPG will automatically output the verification of the signature when it decrypts the message. You don’t have to take any special action to verify the signature you just use the normal -d or –decrypt option, it happens by default.
# When you decrypt the message it will verify the signature
gpg --decrypt message.txt.asc
You can also manually verify a signature for things like a clear signed file with the –verify option like this:
# Verify a signed message that included a signature
gpg --verify message.txt.asc
# Verify and extract original document
gpg --output message.txt message.txt.asc
-
Detached signatures
So far all the signatures we have seen have been embedded in to the file with the message. It is also possible to separate the signature file from the message file. This is called a detached signature.
# Create a separate signature file
gpg --detach-sign message.txt
# Will create message.txt.sig
# This verify will automatically check the signature
# against a file named "message.txt"
gpg --verify message.txt.sig
# Specify the file to check it against
gpg --verify some_signature.sig ./message.txt