Prof. Alessandro Armando

View on GitHub

Introduction to PGP

This document aims to be a gentle introduction to PGP. The text of next section is taken from the post OpenPGP, PGP and GnuPG: What is the difference?. The rest of the document heavily relies on The GNU Privacy Handbook.

Differences among OpenPGP, PGP and GnuPG

PGP (Pretty Good Privacy)

OpenPGP

GnuPG (GNU Privacy Guard)

Summary

Symmetric encryption with PGP

A document can be encrypted with a symmetric cipher by using the --symmetric option.

> gpg --output doc.gpg --symmetric doc.txt
Enter passphrase: <PASSPHRASE GOES HERE>

Note: PGP does note delete the original file (doc.txt) which must be explicitly deleted if you wish so.

To recover the original file you can decrypt it by using PGP:

> gpg --output doc.txt --decrypt doc.gpg
Enter passphrase: <PASSPHRASE GOES HERE>

Exercise - symmetric encryption

As a preliminary step we will create a list of the students attending the lecture. (The istructor will give you instructions.)

During the exercise, each of you will receive by email a message encrypted (as an attachment) by the student that precedes you in the list. (The first student in each group will receive the message by the instructor.) To decrypt the message you must use as passphrase the string obtained by concatenating the name and surname of the person from whom you have received the message (all upcase letters and separated by a single space).

Add you name and surname at a bottom of the list you have received, encrypt the resulting list by using your name and surname (please use the same format described above) and send by email the encrypted message as an attachment to the student that follows you in the list. (The last student must consider the instructor as next.)

Public-key encryption with PGP

Generating a new keypair

The command-line option --full-generate-key is used to create a new primary keypair.

> gpg --full-generate-key
gpg (GnuPG) 1.4.20; Copyright (C) 2015 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.

Please select what kind of key you want:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
Your selection? 

GnuPG is able to create several different types of keypairs, but a primary key must be capable of making signatures:

In all cases it is possible to later add additional subkeys for encryption and signing. For most users the default option is fine.

You must also choose a key size, the lifetime of the key (a key that does not expire is adequate for most users), a user ID (Real Name, Comment and Email Address).

Finally GnuPG needs a passphrase to protect the primary and subordinate private keys that you keep in your possession.

Exchanging keys

To communicate with others you must exchange public keys.

To list the keys on your public keyring use the command-line option --list-keys.

> gpg --list-keys
/home/armando/.gnupg/pubring.gpg
---------------------------------------
pub   1024R/4E1E1D8A 2017-10-14
uid                  Mario Rossi <mario.rossi@gmail.com>
sub   1024R/AFB311B5 2017-10-14

Exporting a public key

> gpg --armor --export mario.rossi@gmail.com
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1

mI0EWeIoYgEEANtnr1fQoGvY4W6A2yIn1TNJgLpIkrL/5vJ70t9c8KiEUTjzxAkj
1yBQ9S2qQLvKfpUAK0Qq6Z+Y5Zyorw200O0oexKwXGTJRaNmIQOHdHvqM4CVRMv3
bJDMmdH64WLwY3XYvZW9kzQA6NlP1+DgNjG3ebWtm8bBOLG4LMxY7Hu3ABEBAAG0
I01hcmlvIFJvc3NpIDxtYXJpby5yb3NzaUBnbWFpbC5jb20+iLgEEwECACIFAlni
KGICGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEKWjdw1OHh2KPugEAMLo
/F8eH8emFQ0xFFLaBzFpJWTPKO1RpCGl1QzIXEkwtpYPKenT5ruXKBcORansl8uG
UUCKsIFqEmsm5YtLQ4ruGhGg24mxrnP6ZBvmqWZNF8b5TJtdaYjJLl05NNK1C6BV
zrsupVT7SlvvsPCVTL9NDT7rxrDGcxBueB233X6vuI0EWeIoYgEEALJaxcM7EEVp
alLz3oiwnmlPtnmcYloDhh3cbn74HpV/ldrrS8JeYHdJ5yjvefek24V4r+7Gxn3J
tBgL9cuqrez8EzkvuGjaIiyyIZHLTJju86DZcTPcODCwWKePjb1DcJ2OOHuaN6s4
2nGOzH6Ia7UWRHeQhdLAHM0ersNReeCVABEBAAGInwQYAQIACQUCWeIoYgIbDAAK
CRClo3cNTh4diveqBACX9hllxteGdZW3+jQl9chlXu3M/eQaAtbcjvSergcYq9S5
f6FGQCOALPDCj15NWUCEFoHCfPji1+JKO1sAfhzmpo9XqA11m63s4gEDCaB/Qn93
mPno4fF7SENw+CNZ7nniEvKhuzBG92AvaiHYG1eHAwtXnIYUAhb+SR0JSP6KAQ==
=AWyM
-----END PGP PUBLIC KEY BLOCK-----

Exercise - exporting keys

  1. Create a new key pair for personal use. Use your real name and a valid email address when asked to do so by GnuPG.
  2. Choose your own passphrase to protect the private key and do not share it with anyone else!
  3. Export the public key and save it to a file.
  4. Upload your public key to the shared folder that has been communicated to you by the istructor.

Importing a public key

A public key may be added to your public keyring with the --import option. (In the sequel we write user> command to indicate that command is executed by user.)

alice> gpg --import blake.gpg
gpg: key 9E98BC16: public key imported
gpg: Total number processed: 1
gpg:               imported: 1
alice> gpg --list-keys
/users/alice/.gnupg/pubring.gpg
---------------------------------------
pub  1024D/BB7576AC 1999-06-04 Alice (Judge) <alice@cyb.org>
sub  1024g/78E9A8FA 1999-06-04

pub  1024D/9E98BC16 1999-06-04 Blake (Executioner) <blake@cyb.org>
sub  1024g/5C8CBD41 1999-06-04
alice> gpg --edit-key blake@cyb.org
pub  1024D/9E98BC16  created: 1999-06-04 expires: never      trust: -/q
sub  1024g/5C8CBD41  created: 1999-06-04 expires: never     
(1)  Blake (Executioner) <blake@cyb.org>

Command> fpr
pub  1024D/9E98BC16 1999-06-04 Blake (Executioner) <blake@cyb.org>
             Fingerprint: 268F 448F CCD7 AF34 183E  52D8 9BDE 1A08 9E98 BC16
Command> sign
             
pub  1024D/9E98BC16  created: 1999-06-04 expires: never      trust: -/q
             Fingerprint: 268F 448F CCD7 AF34 183E  52D8 9BDE 1A08 9E98 BC16

     Blake (Executioner) <blake@cyb.org>

Are you really sure that you want to sign this key
with your key: "Alice (Judge) <alice@cyb.org>"

Really sign?
Command> check
uid  Blake (Executioner) <blake@cyb.org>
sig!       9E98BC16 1999-06-04   [self-signature]
sig!       BB7576AC 1999-06-04   Alice (Judge) <alice@cyb.org>

Exercise - importing, validating and sigining keys

  1. Download the public keys of the people in your group from the shared folder
  2. Import them your into your keyring
  3. Validate (how?) the public keys.
  4. Signs the keys

Listing Key Signatures

The command-line option --list-sigs is like to --list-keys but it additionally displays the key signatures.

> gpg --list-sigs
/home/armando/.gnupg/pubring.gpg
---------------------------------------
pub   rsa3072 2019-11-17 [SC] [expires: 2021-11-16]
      81B88ACDB1F4A829CDDE48E633F0887D7F248E41
uid           [ultimate] Mario Rossi <mario.rossi@gmail.com>
sig 3        33F0887D7F248E41 2019-11-17  Mario Rossi <mario.rossi@gmail.com>
sig          2E962779B10A1CD0 2019-11-17  Elena Verdi <elena.verdi@gmail.com>
sub   rsa3072 2019-11-17 [E] [expires: 2021-11-16]
sig          33F0887D7F248E41 2019-11-17  Mario Rossi <mario.rossi@gmail.com>

In this case, there are two signatures: one generated by Mario Rossi (self-signed) and one by Elena Verdi.

User IDs and Key IDs

A User ID (e.g. real name, email address) are meant to identify the owner of a key.

A Key ID (and fingerprints) is used to reference a key when performing several actions like requesting and sending keys, or when verifying ownership. For example, you’d exchange the fingerprint with the key’s owner on a separate, trusted channel to make sure the key really belongs to the person that claims to own the key.

A Key ID is an identifier calculated from the public key and key creation timestamp. From those, a hashsum is calculated:

Example:

fingerprint: 0D69 E11F 12BD BA07 7B37  26AB 4E1F 799A A4FF 2279
long id:                                    4E1F 799A A4FF 2279
short id:                                             A4FF 2279

Be aware the eight byte short key IDs do not provide a sufficiently large value space, and it is easily possible to generate duplicate keys through collision attacks.

Instead of short key IDs, use at least long key IDs, and when software handles keys, always refer the whole fingerprint.

Web of Trust

Validating a correspondent’s key by personally checking his key’s fingerprint is ok but requires a secure channel to obtain the fingerprint.

PGP uses a powerful and flexible trust model that does not require you to personally validate each key you import.

In the web of trust model, responsibility for validating public keys is delegated to people you trust. For example, suppose

If Alice trusts Blake to properly validate keys that he signs, then Alice can infer that Chloe’s and Dharma’s keys are valid without having to personally check them. She simply uses her validated copy of Blake’s public key to check that Blake’s signatures on Chloe’s and Dharma’s are good.

In practice trust is subjective. For example, Blake’s key is valid to Alice since she signed it, but she may not trust Blake to properly validate keys that he signs. In that case, she would not take Chloe’s and Dharma’s key as valid based on Blake’s signatures alone.

The web of trust model accounts for this by associating with each public key on your keyring an indication of how much you trust the key’s owner. There are four trust levels.

A key’s trust level is something that you alone assign to the key, and it is considered private information. It is not packaged with the key when it is exported; it is even stored separately from your keyrings in a separate database.

The GnuPG key editor may be used to adjust your trust in a key’s owner. The command is trust. In this example Alice edits her trust in Blake and then updates the trust database to recompute which keys are valid based on her new trust in Blake.

alice% gpg --edit-key blake

pub  1024D/8B927C8A  created: 1999-07-02 expires: never      trust: q/f
sub  1024g/C19EA233  created: 1999-07-02 expires: never
(1)  Blake (Executioner) <blake@cyb.org>

Command> trust
pub  1024D/8B927C8A  created: 1999-07-02 expires: never      trust: q/f
sub  1024g/C19EA233  created: 1999-07-02 expires: never
(1)  Blake (Executioner) <blake@cyb.org>

Please decide how far you trust this user to correctly
verify other users' keys (by looking at passports,
checking fingerprints from different sources...)?

 1 = Don't know
 2 = I do NOT trust
 3 = I trust marginally
 4 = I trust fully
 s = please show me more information
 m = back to the main menu

Your decision? 3

pub  1024D/8B927C8A  created: 1999-07-02 expires: never      trust: m/f
sub  1024g/C19EA233  created: 1999-07-02 expires: never
(1)  Blake (Executioner) <blake@cyb.org>

Command> quit
[...]

Trust in the key’s owner and the key’s validity are indicated to the right when the key is displayed. Trust in the owner is displayed first and the key’s validity is second. The four trust/validity levels are abbreviated: unknown (q), none (n), marginal (m), and full (f). In this case, Blake’s key is fully valid since Alice signed it herself. She initially has an unknown trust in Blake to properly sign other keys but decides to trust him marginally.

The web of trust allows a more elaborate algorithm to be used to validate a key. Formerly, a key was considered valid only if you signed it personally. A more flexible algorithm can now be used: a key K is considered valid if it meets two conditions:

  1. it is signed by enough valid keys, meaning
    • you have signed it personally,
    • it has been signed by one fully trusted key, or
    • it has been signed by three marginally trusted keys; and
  2. the path of signed keys leading from K back to your own key is five steps or shorter.

The path length, number of marginally trusted keys required, and number of fully trusted keys required may be adjusted. The numbers given above are the default values used by GnuPG.

The following DAG and table show a web of trust rooted at Alice.

PGP Web of Trust Example

case marginal trust full trust marginal validity full validity
1   Dharma   Blake, Chloe, Dharma, Francis
2 Blake, Dharma   Francis Blake, Chloe, Dharma
3 Chloe, Dharma   Chloe, Francis Blake, Dharma
4 Blake, Chloe, Dharma   Elena Blake, Chloe, Dharma, Francis
5   Blake, Chloe, Elena   Blake, Chloe, Dharma, Elena, Francis

The graph illustrates who has signed who’s keys. The table shows which keys Alice considers valid based on her trust in the other members of the web. This example assumes that two marginally-trusted keys or one fully-trusted key is needed to validate another key. The maximum path length is three.

When computing valid keys in the example, Blake and Dharma’s are always considered fully valid since they were signed directly by Alice. The validity of the other keys depends on trust.

The web of trust model is a flexible approach to the problem of safe public key exchange. It permits you to tune GnuPG to reflect how you use it. At one extreme you may insist on multiple, short paths from your key to another key K in order to trust it. On the other hand, you may be satisfied with longer paths and perhaps as little as one path from your key to the other key K. Requiring multiple, short paths is a strong guarantee that K belongs to whom your think it does. The price, of course, is that it is more difficult to validate keys since you must personally sign more keys than if you accepted fewer and longer paths.

Encrypting and decrypting documents

To encrypt a message the option --encrypt is used.

alice> gpg --output doc.gpg --encrypt --recipient blake@cyb.org doc

To decrypt a message the option --decrypt is used.

blake> gpg --output doc --decrypt doc.gpg

You need a passphrase to unlock the secret key for
user: "Blake (Executioner) <blake@cyb.org>"
1024-bit ELG-E key, ID 5C8CBD41, created 1999-06-04 (main key ID 9E98BC16)

Exercise - sending and receiving messages

  1. Generate and send some text to the student who is next to you in the alphabetical order in such a way that confidentiality is ensured.
  2. Decrypt the message that you have received from the student that precedes you in the alphabetical order. Can you check the authenticity of the message?

Making and verifying signatures

alice> gpg --output doc.sig --sign doc

You need a passphrase to unlock the private key for
user: "Alice (Judge) <alice@cyb.org>"
1024-bit DSA key, ID BB7576AC, created 1999-06-04

Enter passphrase: 
blake> gpg --output doc --decrypt doc.sig
gpg: Signature made Fri Jun  4 12:02:38 1999 CDT using DSA key ID BB7576AC
gpg: Good signature from "Alice (Judge) <alice@cyb.org>"

Clearsigned documents

alice> gpg --clearsign doc

You need a passphrase to unlock the secret key for
user: "Alice (Judge) <alice@cyb.org>"
1024-bit DSA key, ID BB7576AC, created 1999-06-04

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

[...]
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v0.9.7 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iEYEARECAAYFAjdYCQoACgkQJ9S6ULt1dqz6IwCfQ7wP6i/i8HhbcOSKF4ELyQB1
oCoAoOuqpRqEzr4kOkQqHRLE/b8/Rw2k
=y6kj
-----END PGP SIGNATURE-----

Exercise - sending and receiving messages

  1. Generate and send some text to the student who is next to you in the alphabetical order in such a way that the recipient can check the authenticity of the text.
  2. Decrypt the message that you have received from the student that precedes you in the alphabetical order. Can you check the authenticity of the message?

Detached signatures

A detached signature is created using the --detach-sig option.

alice> gpg --output doc.sig --detach-sig doc

You need a passphrase to unlock the secret key for
user: "Alice (Judge) <alice@cyb.org>"
1024-bit DSA key, ID BB7576AC, created 1999-06-04

Enter passphrase: 
Both the document and detached signature are needed to verify the signature. The --verify option can be to check the signature.

blake> gpg --verify doc.sig doc
gpg: Signature made Fri Jun  4 12:38:46 1999 CDT using DSA key ID BB7576AC
gpg: Good signature from "Alice (Judge) <alice@cyb.org>"