Toggle menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

Introduction to gpg key usage

From posixlycorrect wiki


Introduction

The following is an introductory tutorial on how to use GPG keys to send secure and trusted messages across the internet.

GPG is widely used to send secure and verified messages all over the internet, including in the Linux Kernel project! In order for it to work, everyone has to have a key-pair.

Key pairs consist of two cryptographic keys: a public key and a private key. The public key is used to encrypt data or verify digital signatures, and it can be freely shared with others. Conversely, the private key is kept secret and is used to decrypt data encrypted with the corresponding public key or to create digital signatures. When someone wants to send you an encrypted message, they use your public key, which only you can decrypt using your private key. Similarly, when you digitally sign a file, others can verify its authenticity using your public key. This asymmetric key pair system ensures secure communication and data integrity in various applications, such as email encryption and software distribution.

More info on the official website.

In this guide, the following topics will be covered:

  • Generate your personal key pair
  • Export your public key with --armor so you can easily share it
  • Upload your public key to various key servers so you can even more easily share it
  • Encrypt and decrypt a file
  • Setup Thunderbird to send and receive encrypted emails (coming soon)
  • Setup (neo)mutt to send and receive encrypted emails (coming soon)


Prerequisites

All you are going to need is the gnupg package. Get it using your distro's package manager.

Let's get started.


Generating your personal key pair

To create a key pair, run the following command:

$ gpg --full-gen-key

You should get something like this:

Please select what kind of key you want:
   (1) RSA and RSA
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
   (9) ECC (sign and encrypt) *default*
  (10) ECC (sign only)
  (14) Existing key from card
Your selection?

Select option 9 (which is the default anyway), then you'll get something like this:

Please select which elliptic curve you want:
   (1) Curve 25519 *default*
   (4) NIST P-384
   (6) Brainpool P-256
Your selection?

Select the default option again.

Then, choose an expiration date:

Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for?

I normally choose a couple of years. It's not a good idea to have a key never expire.

Now GPG will create an identity for you:

GnuPG needs to construct a user ID to identify your key.

Real name:
Email address:
Comment:

Enter a name to identify yourself (usually first and last name), your email, and optionally a comment. Normally the comment is left blank.

After that, GPG will ask you to add a passphrase to protect your key. Enter a secure passphrase and GPG will have generated your key!

You should see output similar to this:

pub   ed25519/0x1FFAC35E1798174F 2023-06-02 [SC] [expires: 2028-05-31]
      Key fingerprint = 7AA2 77E6 04A4 1739 16BB  B4E9 1FFA C35E 1798 174F
uid                   [ultimate] Fabian Montero <fabian@posixlycorrect.com>
sub   cv25519/0xEA4F0B28F9C039EB 2023-06-02 [E] [expires: 2028-05-31]

This is the typical way in which GPG displays keys. Let's understand this output.


Overview of the anatomy of a GPG key

This will only be a quick overview, if you want more information on this, check out the following links:

Let's take a look at the first line of the output:

pub   ed25519/0x1FFAC35E1798174F 2023-06-02 [SC] [expires: 2028-05-31]

This tells us the type of entry that we're looking at. And it tells us a couple of things:

  • `pub`: This is a public key
  • `ed25519`: This key uses an elliptic curve Diffie–Hellman (ECDH) key agreement scheme (I have no clue what that is, but as I understand it, this is the most secure key technology developed thus far)
  • `0x1FFAC35E1798174F`: is the key ID of your key, this is derived from the key's fingerprint
  • `2023-06-02`: date on which the key was generated
  • `[SC]`: means that this key has the following two capabilities: sign and certify
  • `[expires: 2028-05-31]`: expiration date of the key

The next line looks like this:

      Key fingerprint = 7AA2 77E6 04A4 1739 16BB  B4E9 1FFA C35E 1798 174F

This is the fingerprint of your key (more on what this is in a moment).

The next line looks like this:

uid                   [ultimate] Fabian Montero <fabian@posixlycorrect.com>

This is the uid that corresponds to this key. The `[ultimate]` string means that this key is ultimately trusted. Normally this means that the private key is also available.

Finally, the last line looks like this:

sub   cv25519/0xEA4F0B28F9C039EB 2023-06-02 [E] [expires: 2028-05-31]

This is a subkey of your key. This subkey is bound to your normal key.

  • `sub`: This is a subkey
  • `cv25519`: This key uses an elliptic curve Diffie–Hellman (ECDH) key agreement scheme
  • `0xEA4F0B28F9C039EB`: is the key ID of your subkey, this is derived from the key's fingerprint
  • `2023-06-02`: date on which the key was generated
  • `[E]`: means that this key has the following capability: encrypt
  • `[expires: 2028-05-31]`: expiration date of the key


Exporting your key with --armor

One way to export your public key is to export its armor. To do that, run the following command:

$ gpg --export --armor 7AA277E604A4173916BBB4E91FFAC35E1798174F

Replacing the fingerprint with your key's fingerprint, of course.

This will output something like this:

-----BEGIN PGP PUBLIC KEY BLOCK-----
mDMEZHlROBYJKwYBBAHaRw8BAQdAhzA1JCghQ6KoHOuf6JPQhEmchHLVXFVye4I2
pRUOUMO0KkZhYmlhbiBNb250ZXJvIDxmYWJpYW5AcG9zaXhseWNvcnJlY3QuY29t
PoiUBBMWCgA8FiEEeqJ35gSkFzkWu7TpH/rDXheYF08FAmR5UTgCGwMFCQlmAYAE
CwkIBwQVCgkIBRYCAwEAAh4FAheAAAoJEB/6w14XmBdPP2EA/i9ugFxpIFF6oOQs
clMfr+sNj6Il0OUTJK0dqpp4mGorAP0awa6nfhU8T1Ju7UWr6cfSmnL4bM6M/4Z3
D+AF/L5PBokCMwQQAQoAHRYhBOd6gIv5qVXWaO7qZHP6nJy18CSbBQJkeVKDAAoJ
EHP6nJy18CSbzTkP/Reio0ObRrRW+QSw62ZXrUG0mFcNeeoM9amldCToFRyGnSDu
wtZ9nqwLiTJ01VPBOsEZLsl4VonO3rdadqnMTZ3XqKK9VHBl6UNot3DQ8INDAcko
GW1zvEdxNkpMxhtAja0JkcBdG7+zxc2aEGeKfEna2qDXA+xtYw5+pssOWYMip7hm
jQ2NzYMYav2KYRBC7eXTkAIIIJi/l9pR1IwHtY3a0gfbkQymgCyt5wVG6LneYFIR
+ycNVCObwyP8gFASdId0bWnA23rkilc9ZBOCps/cGfDLM+KQ+sLAWBFBQyQeEjcv
tU+pLXncAEvWy/SFmprVSLDQMMooFaEJMZChojGcCkwAPG1twsihqIA3E44Q3/+G
K0gZN57jGMnfvuQiuLuttOMdu27KwEu++t3YUt0P6S4kARpx51zZJ7A2Yj2u22aM
7EL8qq6KTNdNoS7FgwQkrWbokdDZIl0HV+5TeMQfylPqOPhuFK/1A9qztqknBPVY
QUx2t6FZUgH9sT7uD+5gXxyeqmEIFo2i6D8G/4TEPbKtWivJfeOqDEBn4QEY2nvE
zgJLLU5XCv9xPz5rizRCa+h+kg+i4mH6fLCBCCAPXsbAAo0gUlGJvX4slPh7uPOa
T2r7A/7uezResBzP/L/vostlmjO5c8cOl9Wc6D1kRZq17/AjMUgy6+KR3iVnuDgE
ZHlROBIKKwYBBAGXVQEFAQEHQPRbCS2p8xpt3fRxfyRnDOdH9pULY4NtGmZUS0ve
ZGkTAwEIB4h+BBgWCgAmFiEEeqJ35gSkFzkWu7TpH/rDXheYF08FAmR5UTgCGwwF
CQlmAYAACgkQH/rDXheYF0/65AD+LtDeedCYv9zs+1Ia3DvejVZM256WEH+dRH5h
Pm3RzQ8A/2+bXRnfsgGqacj/kKEL3spuos95ngRNRkrQ39nc1koP
=PAxr
-----END PGP PUBLIC KEY BLOCK-----

That string is what is known as the armor of your key. It can be saved into a file: `fabian.gpg`, for example, and be imported by others like this:

$ gpg --import fabian.gpg

More info on armor in this Unix Stack Exchange question.


Uploading your public key to the internet

You can also upload your key to various key servers, so other people can search for it and download it. To do this, run the following command:

$ gpg --send-keys 7AA277E604A4173916BBB4E91FFAC35E1798174F

Again, replacing my fingerprint with yours.

You can also upload it manually to https://keys.openpgp.org/.


Encrypting and decrypting a file

Now that you have your key pair and you have published your public key, you can start encrypting and decrypting stuff. This is extremely easy:

To encrypt a file called `secrets.txt`, run:

$ gpg -e secrets.txt

GPG will ask you to enter recipients:

You did not specify a user ID. (you may use "-r")

Current recipients:

Enter the user ID.  End with an empty line:

Enter the email address of the recipient, so that the file is encrypted using their public key. This way, only they will be able to decrypt the file using their corresponding private key.

You can add more than one recipient. It is common to add yourself as a recipient; that way, you can also decrypt the file.

This will produce a file called `secrets.txt.gpg`, which is encrypted. You can now send this file safely to the recipient.

To decrypt an encrypted file, run:

$ gpg -d secrets.txt.gpg

GPG will print something like this:

gpg: encrypted with cv25519 key, ID 0xEA4F0B28F9C039EB, created 2023-06-02
      "Fabian Montero <fabian@posixlycorrect.com>"
gpg: using "7AA277E604A4173916BBB4E91FFAC35E1798174F" as default secret key for signing

And the content of the decrypted file will be printed in standard output.

If you have any questions, feel free to email me.