An introduction to GPG / PGP
Pretty Good Privacy is an cryptograhic standard, used for encryption, decryption, verification and signing of various medias. The application ranges from e-mails and files, to whole disk partitions and directories.
GNU Privacy Guard is an open source application of the PGP standard, with various frontends supported. It it widely used for a variety of use cases, namely verifying file integrity from the www, encrypting e-mails, and proving identities. It relies on public-key cryptography for the encryption, meaning generating a key, actually consists of a key-pair, one being secret, the other being public.
Using GPG
Generating Keys
Generate a key:
gpg --full-generate-key
This will run your through a guided key generation, where you can choose key-type, key-size, expiration date, passphrase, and identity to attach it to.
We can now verify that we have generated a new key, by listing the keys in our keyring:
Listing Keys
gpg --list-keys
gpg --list-secret-keys
As the identities of the public/private key pair are indifferent, the commands will give the same output, apart from the pub
/ sec
indication in front of the ID.
The commands will differ in output, when you import a public key, for which you do not have the secret key.
The key format can also be changed using the --keyid-format={none|short|0xshort|long|0xlong}
Fingerprints
The long key IDs can be hard to read for humans, and thus we have fingerprints, which basically splits the ID up into bits of 4, making them easier to read.
This can be used to compare fingerprints, to ensure that the public key you have, actually belongs to the person you think - by comparing fingerprints.
gpg --fingerprint
Here I can see that my publickey, has the fingerprint 79D5 CEBF BA7D 36FC B136 611A 006D 4674 33D5 A927
.
Importing Keys
Importing keys can be done by specifying the key, as a local file on the computer:
gpg --import some.key
Where some.key
, can be either a public or secret key.
Importing can also be done directly, reading from stdin.
curl "https://t1ng.dk/006D467433D5A927.asc" | gpg --import
Should you already have imported the key, gpg will tell you so.
Exporting Keys
Again, we will view the ID's of our keys:
gpg --list-keys
Exporting can be done either with binary keyfiles or as ascii text, with the -a / --armor
flag.
gpg --export <key ID> > public.key
gpg --export --armor <key ID> > publickey.asc
The latter of the commands will give is a human-readable file, beginning with -----BEGIN PGP PUBLIC KEY BLOCK-----
, whereas the first will fill up less disk-space, but be binary.
The binary file, does not have any magic number attached to it, so it will look like raw data.
file public.key
public.key: data
Exporting keys, can also be done, specifying the identity it is attached to:
gpg --export --armor Tinggaard > publickey.asc
gpg --export --armor [email protected] > publickey.asc
The two commands will give the same output.
It is also possible to export a secret key.
gpg --export-secret-key --armor <key ID>
Deleting Keys
To delete a public key, use
gpg --delete-keys <key ID>
And to delete a secret key
gpg --delete-secret-keys <key ID>
Key Servers
Before we get to the more practical use cases of gpg, it is fundamental to know about keyrings, key servers, key signing and key trust.
Your keyring is the file stored on your computer, which holds all of your keys secret. To create an easier way to share keys, keyservers are here to help. A keyserver, is a server on the web, that stores keys from everyone who is willing to push them to said server. Likewise you can pull keys down from other people, assuming their keys are on the server.
Some of the most common key servers include:
- keys.gnupg.net
- keyserver.ubuntu.com
- pgp.mit.edu
To push a key to a key server
gpg --keyserver keys.gnupg.net --send-keys <key ID>
And to recieve a key
gpg --keyserver keys.gnupg.net --recv-keys <key ID>
To update keys already pulled (in case they have have expired, or new subkeys added etc.) do
gpg --keyserver keys.gnupg.net --refresh-keys
Key Signning
To sign a key, means to assign some value to it, indicating how much you trust it.
It can be done like so
gpg --sign-key <key ID>
Encryption
To encrypt a message, we need the recipients public key in our keyring, otherwise gpg does not know how to encrypt the message.
The examples below requires that you have the public key of [email protected]
in your keyring, furthermore if you have not selected your amount of trust in this key, gpg will warn you.
The command below will ascii encrypt message
with [email protected]
's public key, and write the output to message.asc
(default).
gpg --recipient [email protected] --encrypt --armor message
It is also possible to hide the identity of the recipient, meaning that the identity of the recipient is not included in the output.
Decryption still works the same way, but just having the encrypted file, it is not possible to determine if you can decrypt it, because you do not know for whom it is addressed. This is done by replacing the -r / --recipient
with -R / --hidden-recipient
.
Signing
To sign a file, means that you encrypt it, using your own secret key, thus everyone can decrypt it with your public key, but knowing that it can only have originated from you.
There are various options for signing, including both signing and encrypting, resulting in a file encrypted for a specific recipient, signed by you.
It is also possible to change the secret key (not using the default key) used for the signing, using the -u / --local-user
parameter.
-s / --sign
allows you to do a basic signing of a message, indicating that you are the author.--clearsign
signins as ascii, (no--armor
needed), and includes the original message as a header - as the data is not secret anyway, because everyone can read your public key.-b / --detach-sign
signs a message, but does not include the message itself, meaning it needs to already be present on your computer, before the verification can take place.
To sign message
, outputting message.gpg
gpg --sign message
To clearsign message
, using a key, yielding message.asc
gpg --clearsign --local-user <key ID> message
To detach sign message
, yielding message.sig
gpg --detach-sign message
Decryption
To decrypt a message, naturally you have to have the secret key, pairing with the public key, used for the encryption, in your keyring. Or the public key, if the message is signed.
Decrypting can be done of both encrypted, signed, as well as encrypted AND signed messages.
gpg --decrypt message.gpg
- Using
-d / --decrypt
on an encrypted message, yields the unencrypted message. - Using
-d / --decrypt
on a signed message, shows the author, as well as the original message. - Using
-d / --decrypt
on an encrypted, signed message shows the unencrypted message as well as the author.
Verifying
Verifying is only done on signatures, and does not show the do the decrypted message, but only verifies who the author of the message is.
To verify the authenticy of message
, using the signature message.sig
.
gpg --verify message.sig
This assumes you already have message
in the same directory.
However verifying can also be done of .asc
and .gpg
files created using --clearsign
or --sign
, which does not require the original message to be present.
If the filename is not exactly the same as the signature, apart from the .sig
ending, gpg will fail.
This can however be resolved, by specifying the file to verify as a second argument.
Assuming the file to verify is original
and NOT message
.
gpg --verify message.sig original
Symmetric Encryption
Symmetric Encryption does not require a public/private key pair, as the same key (password) is used for encryption and decryption. Instead the recipient and you, both need to know the password.
To symmetrically encrypt message
to symmetric.asc
use
gpg --symmetric --armor --output symmetric.asc message
gpg will then prompt you for a password to use for the encryption.
Abbreviations
Full command | Shortened |
---|---|
--list-keys |
-k |
--list-secret-keys |
-K |
--armor |
-a |
--output |
-o |
--encrypt |
-e |
--decrypt |
-d |
--recipient |
-r |
--hidden-recipient |
-R |
--sign |
-s |
--detach-sign |
-b |
--local-user |
-u |
--verbose |
-v |
Examples
List public keys
gpg -k
Encrypt and armor message
for [email protected]
.
gpg -ear [email protected] message
Sign and encrypt message
for [email protected]
, and write it to sig_enc.gpg
gpg -seau <key ID> -r [email protected] -o sig_enc.gpg message
Detach-sign and armor message
and write the output to signature.sig
.
gpg -bao signature.sig message
And of course the infamous manual, or simply a quick search on the web.
man gpg