Gnu Privacy Guard (GnuPG) is a cryptography suite installed on most linux operating systems that can be used to encrypt files and information, as well as performing message and file integrity checks with digital signatures. This is a quick rundown on how to use certian features within GnuPG, while illustrating how they work.

Symmetric Cryptography

Symmetric encryption (cryptography that uses the same key or password to encrypt and decrypt) is useful when you only need to keep information to yourself without sharing it. This is useful for a personal journal, or for integrating into your cloud backups.

Same Key Encryption

For example, you can have a file called message.txt that contains this message:

Hello World!

This message can be encrypted using gpg with the following command:

$ gpg --symmetric -a message.txt

You will be prompted to enter a passphrase for the file. A new file will be created called message.txt.asc. If you try to read it, it will look something like this:

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

jA0ECQMC5422aTHYW/7/0k0BBL3tRxeH74x2j6I2jq26d0oCNaamrx5HBgZ0utRl
o8oC9PvxZqpebBy5ikMPlcwg51rDfkNiq4EuGIF9kGS/2DGz89vf98gkdJOE2Q==
=KIxs
-----END PGP MESSAGE-----

Note: You can also use this to encrypt any sort of file, not just text files.

Without the correct passphrase, you will not be able to make sense of this ciphertext. Decrypting the message is almost as easy as encrypting it:

$ gpg --decrypt message.txt.asc
gpg: AES256 encrypted data
gpg: encrypted with 1 passphrase
Hello World!

Operating systems like Ubuntu may have a password manager that has cached your passphrase for a short time. If that is the case, then GnuPG might decrypt the message without any additional input. If not, then you will need to enter the correct passphrase to decode the message.

Caveats

While symmetric encryption is extremely easy and simple to understand, it offers limited security. While the cipher is encrypted with is strong, the security of the message lies in the secrecy of the passphrase. Anyone who learns of the passphrase can read the message. Symmetric encryption offers no means to check for integrity, meaning anyone with the passphrase can also modify the message or files that are encrypted without your knowledge. Symmetric encryption is best used if you need to keep files available to one person, and one person only.

Asymmetric Cryptography

Asymmetric, or public-key cryptography, involves ciphers that use two different keys to keep information safe:

  • Public key - Used to decrypt and verify information and data. This is shared for everyone to use.
  • Private/Secret key - Used to encrypt and digitally sign information. This should only be in the possession of the person who owns the key, and nobody else.

Unlike symmetric cryptography, asymmetric cryptography allows you to communicate secret messages without having to share a secret passphrase.

Both keys in the key-pair are mathematically related. Messages encrypted with a private key can only be decrypted with it's corresponding public key. Contrarywise, a message encrypted with a public key can also only be decrypted with it's corresponding private key. Lastly, a message that was digitally signed with a private key can only be verified with it's corresponding public key.

Creating a keypair

A new keypair can be created for a user named Alice with the --generate-key command:

$ gpg --generate-key
gpg (GnuPG) 2.2.4; Copyright (C) 2017 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: Alice
Email address: alice-demo@darkangle.net
You selected this USER-ID:
    "Alice <alice-demo@darkangle.net>"

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.
gpg: key BBDED47DF3F9DFA9 marked as ultimately trusted
gpg: revocation certificate stored as '/home/Alice/.gnupg/openpgp-revocs.d/F6A211A26A561F58DFCA48AEBBDED47DF3F9DFA9.rev'
public and secret key created and signed.

pub   rsa3072 2019-01-02 [SC] [expires: 2021-01-01]
      F6A211A26A561F58DFCA48AEBBDED47DF3F9DFA9
uid                      Alice <alice-demo@darkangle.net>
sub   rsa3072 2019-01-02 [E] [expires: 2021-01-01]

Note: The --full-generate-key command can be used to get a full interactive setup for the key-pair.

Once both keys are generated, they will be stored in your keyring. The keyring is typically stored in it's own file: ~/.gnupg/pubring.kbx. You can view the keys you have in your possession with the --list-keys command:

$ gpg --list-keys
gpg: checking the trustdb
gpg: marginals needed: 3  completes needed: 1  trust model: pgp
gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
gpg: next trustdb check due at 2021-01-01
/home/Alice/.gnupg/pubring.kbx
--------------------------------
pub   rsa3072 2019-01-02 [SC] [expires: 2021-01-01]
      F6A211A26A561F58DFCA48AEBBDED47DF3F9DFA9
uid           [ultimate] Alice <alice-demo@darkangle.net>
sub   rsa3072 2019-01-02 [E] [expires: 2021-01-01]

A very important thing to note about the a public key, is it's fingerprint. A fingerprint is a series of hexadecimal digits that is computed for they key, and is unique to a public key. This can be displayed with the --fingerprint command:

gpg --fingerprint Alice
pub   rsa3072 2019-01-02 [SC] [expires: 2021-01-01]
      F6A2 11A2 6A56 1F58 DFCA  48AE BBDE D47D F3F9 DFA9
uid           [ultimate] Alice <alice-demo@darkangle.net>
sub   rsa3072 2019-01-02 [E] [expires: 2021-01-01]

The fingerprint for Alice's key is F6A2 11A2 6A56 1F58 DFCA 48AE BBDE D47D F3F9 DFA9, and she would also provide this fingerprint to other people so that they are aware that this fingerprint is unique to the public key she is using.

Importing public keys

Before using asymmetric cryptography to communicate securely, you will also need the public key of your correspondent. They will also require your public key as well. Below is Bobby's public key that he will be sharing to communicate with others that use PGP. When exported from your keyring (which can be done with the --export command), the public key will resemble this:

-----BEGIN PGP PUBLIC KEY BLOCK-----

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
SKabi3d9tGXMDj7aiXzZ/9VDuWHiLt5t
=sFRJ
-----END PGP PUBLIC KEY BLOCK-----

With this public key saved to it's own file, we can import the key into our keyring with the --import command:

$ gpg --import bobby.pub.asc
gpg: key 8D13EB84ABF9E8A7: public key "Bobby <bobby-demo@darkangle.net>" imported
gpg: Total number processed: 1
gpg:               imported: 1

Encrypting/Decrypting With Key-pairs

While messages encrypted with one key in a keypair can be decrypted with the other corresponding key, this does introduce issues. A message encrypted with a public key, while it can only be read by someone with the private key, there is no way the private key holder can verify the sender's identity. Contrarywise, messages encrypted with a private key assures that it came from the private key owner, but is not secret, as anyone with the author's public key can read it. Both correspondents, Alice and Bobby (or Bob), will use both their own private key, and the other persons public key to encrypt and decrypt information. This way, they are the only two people on the planet that can read encrypt and decrypt the messages:

Alice is wanting to send a message to Bob, which is stored in a messagetobob.txt file:

Hello B,

Lets meet at Market Square.

-A

Alice is going to encrypt the message so only Bob and herself can read it with the --encrypt command, and include parameters that specify the user's private key that is encrypting the message (using --user), and who it is being sent to (using --recipient):

$ gpg --encrypt -a --user Alice --recipient Bobby messagetobob.txt 
gpg: 05F732D9E4586152: There is no assurance this key belongs to the named user
sub  rsa3072/05F732D9E4586152 2019-01-06 Bobby <bobby-demo@darkangle.net>
 Primary key fingerprint: 9514 A70F 863B 0D08 986A  474A 8D13 EB84 ABF9 E8A7
      Subkey fingerprint: 8A2B 98E1 81AC 550D 8C56  9544 05F7 32D9 E458 6152

It is NOT certain that the key belongs to the person named
in the user ID.  If you *really* know what you are doing,
you may answer the next question with yes.

Use this key anyway? (y/N) Y

Once Bobby receives the message, he can then decrypt it with the --decrypt command:

$ gpg --decrypt messagetobob.txt.asc 
gpg: encrypted with 3072-bit RSA key, ID E37B5FFB688DE18C, created 2019-01-02
      "Alice <alice-demo@darkangle.net>"
gpg: encrypted with 3072-bit RSA key, ID 05F732D9E4586152, created 2019-01-06
      "Bobby <bobby-demo@darkangle.net>"
Hello B,

Lets meet at Market Square.

-A

While these steps provide a fair amount of certainty that both Alice and Bobby are communicating securely, merely encrypting the information does not provide any integrity checks. What this means is that in the event that this were to be hit by a successful Man In The Middle attack, the attacker could not only read the message, but also replay the message in a modified form with no way to tell it was altered. To mitigate the threat of a man in the middle attack, you would need to use digital signatures.

Signing/Verifying Messages

Signing messages allows users to create digital signatures to verify the integrity of a message. A Digital Signature is a hash value, or unique series of characters that can only be generated by a private key and the message in it's unmodified form. If the message gets to the sender unmodified, then the recipient will be able to verify the message successfully. If it was modified, then verification will fail.

Man In The Middle

When Bob signs a message with the --clear-sign command, it is going to create a file with contents that resemble this:

$ gpg --clear-sign -a --local-user Bobby messagetoalice.txt
$ cat messagetoalice.txt.asc
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Hello A,

Sure, I can be there at 1800. See you there! :)

- -B
-----BEGIN PGP SIGNATURE-----

iQHNBAEBCAA3FiEElRSnD4Y7DQiYakdKjRPrhKv56KcFAlw2nBwZHGJvYmJ5LWRl
bW9AZGFya2FuZ2xlLm5ldAAKCRCNE+uEq/nopzEPDACN1tgvUdkBRP0fwr0WYw0T
s6yo3U0OP5J0QqxLUw4nes6zx5jbbzGIbi3yBfloLtLY+0VyuoR3XDrULoICBsU7
EAIz5iYYD7OmtUllK7sInwx//9fPFa7zsezD1+oaORMeasuPXT3VZzJNYigQP/3P
9QFbiA0+6Un4FRHWsdtCFfOYGOllzv0bqdycQ6QgMEIHaBRlZSFezUWjJY1pWvbZ
PqcM3etYM5Ms90tP7SRk2v2TIzR5N4KA0TS4xbym5BmkSCtl8MVsl28TiQpIuCTr
NVpCsVWYY6zgbMDrQbwEtMXweMcNVMsDui5v9CattU5VOR7sfJ9tvJSK8qR9VOYV
ggX1crJ/xHWW4Sxrd1OePMu6aFeND5dMjsgE9LP6RJL3hi1+3ZCtJmJR12KDFbW1
KFT5zyk7O63YpricJJI4+X9FGg72UCXIbtX5+xK0fm0YAlY2UBcWgFhniZL8lhbA
JZeg1uNcMZXqAwKIvncJ9tb9DGo7pyvXvsFBThnd/DI=
=2Cl0
-----END PGP SIGNATURE-----

In the file with the signed message, the text below the line -----BEGIN PGP SIGNED MESSAGE----- is the actual message that Bobby wrote. The text in between the -----BEGIN PGP SIGNATURE----- and -----END PGP SIGNATURE----- lines are the hash value that can only be generated with Bobby's private key, and the exact version of the message he wrote. If either of these are altered, then GnuPG will fail to verify the message.

Note: The --sign command should be sufficient for signing messages. You can also use --detach-sign for putting the signature in it's own file, which is ideal for signing important files like disc images. We are using --clear-sign to best illustrate how digital signatures work, and is ideal for signing publicly posted messages, such as warrant canaries.

The message is sent to Alice. However she has doubts about the authenticity of the message when she check's for it using the --verify command:

$ gpg --verify signedmessagetoalice.txt.asc
gpg: Signature made Wed 09 Jan 2019 05:13:00 PM PST
gpg:                using RSA key 9514A70F863B0D08986A474A8D13EB84ABF9E8A7
gpg:                issuer "bobby-demo@darkangle.net"
gpg: BAD signature from "Bobby <bobby-demo@darkangle.net>" [unknown]

Looking at the file, we can see that the message was modified:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Hello A,

Uh, can we meet at Lonsdale instead? Downtown is a bit of a drive.

- -B
-----BEGIN PGP SIGNATURE-----

iQHNBAEBCAA3FiEElRSnD4Y7DQiYakdKjRPrhKv56KcFAlw2nBwZHGJvYmJ5LWRl
bW9AZGFya2FuZ2xlLm5ldAAKCRCNE+uEq/nopzEPDACN1tgvUdkBRP0fwr0WYw0T
s6yo3U0OP5J0QqxLUw4nes6zx5jbbzGIbi3yBfloLtLY+0VyuoR3XDrULoICBsU7
EAIz5iYYD7OmtUllK7sInwx//9fPFa7zsezD1+oaORMeasuPXT3VZzJNYigQP/3P
9QFbiA0+6Un4FRHWsdtCFfOYGOllzv0bqdycQ6QgMEIHaBRlZSFezUWjJY1pWvbZ
PqcM3etYM5Ms90tP7SRk2v2TIzR5N4KA0TS4xbym5BmkSCtl8MVsl28TiQpIuCTr
NVpCsVWYY6zgbMDrQbwEtMXweMcNVMsDui5v9CattU5VOR7sfJ9tvJSK8qR9VOYV
ggX1crJ/xHWW4Sxrd1OePMu6aFeND5dMjsgE9LP6RJL3hi1+3ZCtJmJR12KDFbW1
KFT5zyk7O63YpricJJI4+X9FGg72UCXIbtX5+xK0fm0YAlY2UBcWgFhniZL8lhbA
JZeg1uNcMZXqAwKIvncJ9tb9DGo7pyvXvsFBThnd/DI=
=2Cl0
-----END PGP SIGNATURE-----

Using digital signatures, Alice was able to check whether or not this message was altered. As we can see, this is a totally different message then what Bobby had written, and GnuPG confirmed it.

Signing and Encrypting Messages

Alice now decides to send Bobby a message that is both signed and encrypted, which can be done using both --sign and --encrypt:

$ cat messagetobob2.txt
Hey B,

I think someone is messing with us. Your reply failed a signature check.

Be sure to use --sign and --encrypt! :)

-A
$ gpg --sign --encrypt -a --local-user Alice --recipient Bobby messagetobob2.txt
gpg: 05F732D9E4586152: There is no assurance this key belongs to the named user
sub  rsa3072/05F732D9E4586152 2019-01-06 Bobby <bobby-demo@darkangle.net>
 Primary key fingerprint: 9514 A70F 863B 0D08 986A  474A 8D13 EB84 ABF9 E8A7
      Subkey fingerprint: 8A2B 98E1 81AC 550D 8C56  9544 05F7 32D9 E458 6152

It is NOT certain that the key belongs to the person named
in the user ID.  If you *really* know what you are doing,
you may answer the next question with yes.

Use this key anyway? (y/N) y

Once Bobby receives the message, he can use the --decrypt command to decrypt and read it. Because is was signed, GnuPG will also try to verify the digital signature to make sure that the message was not tampered with.

gpg --decrypt messagetobob2.txt.ascgpg: encrypted with 3072-bit RSA key, ID 05F732D9E4586152, created 2019-01-06
      "Bobby <bobby-demo@darkangle.net>"
Hey B,

I think someone is messing with us. Your reply failed a signature check.

Be sure to use --sign and --encrypt! :)

-A
gpg: Signature made Wed 09 Jan 2019 09:05:33 PM EST
gpg:                using RSA key F6A211A26A561F58DFCA48AEBBDED47DF3F9DFA9
gpg:                issuer "alice-demo@darkangle.net"
gpg: Good signature from "Alice <alice-demo@darkangle.net>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: F6A2 11A2 6A56 1F58 DFCA  48AE BBDE D47D F3F9 DFA9

Bobby not only received the message in it's encrypted form, but also successfully verified Alice's signature, so he knows she wrote it.

Conclusion

GnuPG is a cryptography suite that allows you to protect the confidentiality of information, as well as it's integrity.

Using symmetric cryptography (the --symmetric command), we can easily encrypt and decrypt files using a passphrase, but it's security depends on the secrecy of the passphrase, and distributing it puts it at risk.

We can use asymmetric, or public-key, cryptography to communicate securely without the need for a shared secret.

The --generate-key command produces a key pair consisting of a private key and a public key. What is encrypted with one can be decrypted with the other. Messages signed with a private key can be checked with the corresponding public key.

Public keys will need to be exchanged to communicate with asymmetric cryptography. You can export your public key with the --export command. Public keys can be imported with the --import command. A public key's fingerprint can also be displayed with the --fingerprint command. You should make sure that the fingerprint of a public key matches with the same keypair that your correspondent is using to confirm that you are importing the correct public key.

The --encrypt command encrypts a message using asymmetric cryptography. The --local-user option specifies which private key is being used. The --recipient option specifies whose public key you're using. Using both options will ensure that only the sender and recipient and read the messages. The --decrypt command is used to decrypt a message.

The --sign command (or --clear-sign, as demonstrated) will create a digital signature which can only be generated with a specifically written message, and a specific private key. The --verify command can be used to check the integrity of a signed message. If the message or digital signature is altered, it will fail the check. This protects a message from being modified and replayed in a Main In The Middle attack.

Throughout the article, the -a option has been used. This alters the terminal output of any cryptographic cipher text or hashes into an ASCII armored format that can be neatly printed, as well as copied and pasted into text editors and sites. This is optional, but without the ASCII armored output, it would not be possible to put the keys, cipher text, and digital signatures in this article as neatly as I did.

Also, sending a single file between one user and another to keep in constant contact is very impractical. However, there are tools like Enigmail that actually builds upon GnuPG to encrypt email communications.

Other Resources

  • GnuPG.org - The Official Gnu Privacy Guard website where you can download this software, review documentation, download other versions of it, and contribute.
  • Surveillance Self-Defense - A project of the Electronic Frontier Foundation (EFF) which aims to educate others on information security, and provides guides on how to use privacy tools effectively.
  • Email Self-Defense - A guide set up by the Free Software Foundation (FSF) that illustrates how to use GnuPG with email clients like Thunderbird.
  • Keybase - An online service that uses PGP to validate a user's online presence across social networks. It also has secure communication features, and also allows you to publish your public key.

Creative Commons License
This work is licensed under a Creative Commons Attribution 4.0 International License.