Ryan Jacobs


GPG Part 2

Introduction

Welcome back! In this tutorial we will explore even more GPG concepts, such as keyservers, importing keys, and signing keys. Oh fun! (By the way, I assume you understand everything covered in GPG - Part 1.)

First Up: Keyservers

Right now you may be wondering, "Hey Ryan, what the heck is a keyserver and why would I need one?" And that's great, because I'm about to tell you.

You see, in layman's terms a keyserver is a computer way off in who knows where that collects and serves Public Keys. Why is this useful? Well, now anyone who has access to that keyserver now has access to thousands of Public Keys. We don't need to send an email everytime we want someone's Public Key.

So now we will upload our Public Key to the keyserver: pgp.mit.edu

# Find out our pub Key_ID
[email protected] ~ $ gpg --list-keys
/home/ryan/.gnupg/pubring.gpg
-----------------------------
pub   rsa4096/CEED707A 2014-12-13
uid       [ultimate] Ryan Jacobs <[email protected]>
sub   rsa4096/26C73A2F 2014-12-13

# Upload our Public Key (found from prior command)
[email protected] ~ $ gpg --keyserver pgp.mit.edu --send-keys CEED707A
gpg: sending key CEED707A to hkp server pgp.mit.edu

Importing Keys

Rember that thing called a "keyserver"? Okay, good. So say we're working with a guy, and we want to send him an encrypted message that only he can read. Well, in order for us to encrypt something that only he can decrypt, we need his Public Key. And how do we do that? A keyserver!

Let's import his key! By the way, "him" is really me.

[email protected] ~ $ gpg --keyserver pgp.mit.edu --search-keys 'Ryan Jacobs'
gpg: searching for "Ryan Jacobs" from hkp server pgp.mit.edu
(1)     Ryan Jacobs <[email protected]>
          4096 bit RSA key CEED707A, created: 2014-12-13
(2)     Ryan Jacobs <[email protected]>
          2048 bit RSA key D49FDE43, created: 2014-10-28
(3)     Ryan Jacobs <[email protected]>
          2048 bit RSA key 34134FFB, created: 2014-02-08
(4)     Ryan Jacobs <[email protected]>
        Ryan Jacobs (Dukelana) <[email protected]>
          4096 bit RSA key 5F8A8181, created: 2013-09-30 (revoked)
(5)     Ryan Jacobs (7 day file encryption testing key) <[email protected]
          4096 bit RSA key 491D92BF, created: 2013-09-28, expires: 2013-10-05 (expired)
(6)     Ryan Jacobs <[email protected]>
          2048 bit RSA key 5DABDC7F, created: 2013-06-10, expires: 2013-06-17 (expired)
(7)     Ryan Jacobs <[email protected]>
          1024 bit DSA key B1D60BA1, created: 2001-02-14
(8)     Ryan Jacobs <[email protected]>
          2048 bit RSA key 0C93AE23, created: 2001-02-14
gpg: requesting key CEED707A from hkp server pgp.mit.edu
gpg: key CEED707A: "Ryan Jacobs <[email protected]>" 1 new signature
gpg: Total number processed: 1
gpg:         new signatures: 1

[email protected] ~ $ gpg --sign-key CEED707A # Trust the key

Yay! We got my key! (By the way, CEED707A is my Key_ID.)
There may need to be some communication via email or other to determine which Key_ID is the person's you want.

Using an Imported Key

Now that we have my key, let's encrypt a message.

# Create file
[email protected] ~/example $ echo "I love pink poodles." > secret_message.txt
[email protected] ~/example $ ls
secret_message.txt

# Encrypt the file
[email protected] ~/example $ gpg -a -e -r Ryan secret_message.txt
[email protected] ~/example $ ls
secret_message.txt  secret_message.txt.asc

# Remove the unencrypted file
[email protected] ~/example $ rm secret_message.txt
[email protected] ~/example $ ls
secret_message.txt.asc

# What does the message say?
# (gibberish to us humans)
[email protected] ~/example $ cat secret_message.txt.asc
-----BEGIN PGP MESSAGE-----
Version: GnuPG v2

-----BEGIN PGP MESSAGE-----
Version: GnuPG v2

hQIMAyE672omxzovAQ//cCf3TL0FWcUF6BR/mVMXhzzFR6GuiRo6I2E2GPrs8E6U
VqojYpjYEVChMTXg7h1wrj8npfCkHbqZxwqMmQOhfo12tJLcdmtxDMYgwwoClzAF
373ume8eOv6QzxQ7LXykXPoe8bqchshFQnQRjIZKKh6MPoSlFqkJOdzdYjpOYGmC
ilH9Hqf+xCyeqneXX2r+nd7Z+yupdSERnrl4kt88X+KMasoFBGvENHE3tJRjI0e/
C8eeNroztuGOdFHVO+B8DDrCE/i0p4axwqlNPfYV65n4LGitkIw7D8X1CyhO0r0o
8QCNNauqLh+eQ9jwgbFCOSTSacunaKhnMTEI2+9isCptsUZ/6GDbZSU4YhWuEHl7
k1r7qx9q5pFFSA5quVdWFlFYAXWMO2sx/FgdmgpCwP7UTUh2hMKPHX30XkZsQWbQ
aQdPCtCLUEGk5bEP+4egjsjKJgr2zuy4BKSj9FyhVLHvRGysN1llXJuCseflQml0
TC7SNCU1H2EJfBHeWKgUzkyTIaEIoFSCCuK/kh9vi7VoBCyH+vK0i0TzUSK/xzA2
RvOE1KtuqVZoNbH2OFb9d8Grhh8k6SyYveN2cSHtMysI3pqrLCSy8OXRMrKe0EiM
Il0m3bZKaSo4FKeSp5p2ixPE4dUV8mputLOl4RVthWNTd+tkdFleCpKMfRtFvHLS
YgGG6vNyAvN8NpQRLz5UsuofXpJ62aBay1hYxeUkWJP49evR7q0ED412kYMG0oNR
Suyl/aMLI4anyrxKae5ENVNCHJvplAWiXUQbMiapizKPSXw/+cCCKLjtr1o+zxjG
+hxQ
=2/VC

-----END PGP MESSAGE-----

Yay! We encrypted a file with someone else's Public Key! Particularly mine!

Now if you try to decrypt this file, you'll find that you can't. Why? You don't have the Private Key!

# What happens when you decrypt without the private key?
[email protected]_computer ~ $ gpg secret_message.txt.asc
gpg: decryption failed: No secret key
# Oh no! It doesn't work!
# What about when you have the private key?
[email protected] ~/example $ gpg secret_message.txt.asc

You need a passphrase to unlock the secret key for user: "Ryan Jacobs <[email protected]>"
4096-bit RSA key, ID 26C73A2F, created 2014-12-13 (main key ID CEED707A)

gpg: encrypted with 4096-bit RSA key, ID 26C73A2F, created 2014-12-13
      "Ryan Jacobs <[email protected]>"

[email protected] ~/example $ ls
secret_message.txt  secret_message.txt.asc
[email protected] ~/example $ cat secret_message.txt
I love pink poodles.
# Ooh... big surprise, it works.

GPG Signing

In GPG, signing is used in two distinct ways:

  1. To ensure that a file will not be tampered with (protect its integrity)
  2. To show that you trust someone's key

The first use is when you sign a file to ensure it's integrity. Think checksums. If someone modifies what you said in an email and it was GPG signed, 'gpg --verify' will let you know that a change has been made and the signature doesn't match up.

Here's an example:

# Sign a file to protect integrity
[email protected] ~/example $ echo "Do not tamper with this message." > dont_tamper.txt
[email protected] ~/example $ gpg --clearsign dont_tamper.txt && rm dont_tamper.txt

# Verify the file's integrity
[email protected] ~/example $ gpg --verify dont_tamper.txt.asc
gpg: Signature made Sat 13 Dec 2014 04:27:04 PM PST using RSA key ID CEED707A
gpg: Good signature from "Ryan Jacobs <[email protected]>" [ultimate]

# Modify the file, then verify integrity
[email protected] ~/example $ sed -i 's/Do not/Please/g' dont_tamper.txt.asc # Replace 'Do not' with 'Please'
[email protected] ~/example $ gpg --verify dont_tamper.txt.asc
gpg: Signature made Sat 13 Dec 2014 04:27:04 PM PST using RSA key ID CEED707A
gpg: BAD signature from "Ryan Jacobs <[email protected]>" [ultimate]

Difference between --sign and --clearsign:

# --sign vs --clearsign
--sign       # sign & output binary; good for non-text files, e.g. images
--clearsign  # sign & output ascii;  good for text files,     e.g. emails

Steps to sign someone's key:

  1. Get their Key_ID and fingerprint.
  2. Preferably meet in person. Ask for their Key_ID and fingerprint.
  3. Download their key.
  4. gpg --keyserver pgp.mit.edu --recv-keys <Key_ID>
  5. Verify fingerprints are the same.
  6. gpg --fingerprint <Key_ID>
  7. Sign their key.
  8. gpg --sign-key <Key_ID>
  9. Upload their key back to the keyserver.
  10. gpg --keyserver pgp.mit.edu --send-key <Key_ID>