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 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:
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.
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, 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
$ 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: firstname.lastname@example.org You selected this USER-ID: "Alice <email@example.com>" 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 <firstname.lastname@example.org> sub rsa3072 2019-01-02 [E] [expires: 2021-01-01]
--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
$ 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 <email@example.com> 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
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 <firstname.lastname@example.org> 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
$ gpg --import bobby.pub.asc gpg: key 8D13EB84ABF9E8A7: public key "Bobby <email@example.com>" 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
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
$ 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 <firstname.lastname@example.org> 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
$ gpg --decrypt messagetobob.txt.asc gpg: encrypted with 3072-bit RSA key, ID E37B5FFB688DE18C, created 2019-01-02 "Alice <email@example.com>" gpg: encrypted with 3072-bit RSA key, ID 05F732D9E4586152, created 2019-01-06 "Bobby <firstname.lastname@example.org>" 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 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.
--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
$ gpg --verify signedmessagetoalice.txt.asc gpg: Signature made Wed 09 Jan 2019 05:13:00 PM PST gpg: using RSA key 9514A70F863B0D08986A474A8D13EB84ABF9E8A7 gpg: issuer "email@example.com" gpg: BAD signature from "Bobby <firstname.lastname@example.org>" [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
$ 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 <email@example.com> 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 <firstname.lastname@example.org>" 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 "email@example.com" gpg: Good signature from "Alice <firstname.lastname@example.org>" [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.
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.
--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.
--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.
--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.
- 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.
This work is licensed under a Creative Commons Attribution 4.0 International License.