How to verify PGP signatures

How to verify PGP signatures
Ochaun Marshall
Author: Ochaun Marshall
Share:

PGP (Pretty Good Privacy) is an encryption software that is mostly known for its use in email. It is used for encrypting, decrypting, and signing emails and files. Today we’ll focus on two of its most valuable features: verification and signing.   

Why check PGP signatures?

Signing and verifying the signatures is important for data integrity. Recall the CIA triad. For any message to have good data integrity, we want authenticity and nonrepudiation. Authenticity simply states that the message is genuine. Nonrepudiation means that we are able to verify the origin of some communication. You can’t blindly trust anything on the internet. Verifying PGP signatures allows us to verify that the file or message came from a trusted source, since it has been signed with the author’s private key. The private key is something that only the author alone should have access to.  In order to verify it’s authentic, we would only need the signer’s public key.

How to use GPG to verify signature

In this post we’re going to verify the PGP fingerprint from NMAP. We’ll need three things: 

  1. .asc file, or PGP signature 
  2. The author’s verified public key
  3. PGP utility program

First, we’ll get the PGP signature. NMAP provides a tutorial on this, but doesn’t walk through the signing process at the end, which is important for fully trusting a key. I’ve downloaded the nmap-7.92-win32.zip file and it’s .asc signature and placed them in the  /client_code/pgp directory. 

vagrant@vagrant:/client_code/pgp$ ls

nmap-7.92-setup.exe.digest.txt  nmap-7.92-win32.zip.asc  nmap_gpgkeys.txt
vagrant@vagrant:/client_code/pgp$ cat nmap-7.92-win32.zip.asc

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

iF0EABECAB0WIQRDbWarmnmEJf2g4/gBr58Da5NV0AUCYQ8ebQAKCRABr58Da5NV

0Iw5AJ4mQs+zFATXvQS21IvmkEVRgImoBwCfb6RUKPpVeaf4A9jQl6G/lPVOs+8=

=bXfK

-----END PGP SIGNATURE-----

Next we need NMAP’s public key which is available at https://svn.nmap.org/nmap/docs/nmap_gpgkeys.txt. If you’re especially suspicious you can find the key in key directories like MIT PGP directory. Either way the email associated with it should be fyodor@insecure.org with the following fingerprint BB61 D057 C0D7 DCEF E730  996C 1AF6 EC50 3359 9B5F.  This information about his key is also available on the Github repo, and in Fyodor’s book, both printed (page 27) and online versions.

You may be wondering where to find a PGP utility. If you’re running linux or macOS, GNU Privacy Guard (GPG) is preinstalled on most distributions. Windows also has a standalone utility for download as well. Here we will be using the virtual machine from the Static Analysis TTP Repo

From here it’s straight forward. Just verify the .asc file like so:

vagrant@vagrant:/client_code/pgp$ gpg --verify nmap-7.92-win32.zip.asc

gpg: assuming signed data in 'nmap-7.92-win32.zip'

gpg: Signature made Sat 07 Aug 2021 11:59:41 PM UTC

gpg:                using DSA key 436D66AB9A798425FDA0E3F801AF9F036B9355D0

gpg: checking the trustdb

gpg: no ultimately trusted keys found

gpg: Good signature from "Nmap Project Signing Key (http://www.insecure.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: 436D 66AB 9A79 8425 FDA0  E3F8 01AF 9F03 6B93 55D0

The important part is “gpg: Good signature from "Nmap Project Signing Key (http://www.insecure.org/)" [unknown]”. You may be alarmed by the Warning at the end. That is because we need to tell GPG we trust this key. 

Warning: this key is not certified with a trusted signature

This warning appears because GPG has no way of automatically trusting keys. You tell the program which keys you trust by setting a trust level and signing them. You shouldn’t sign random keys from the internet. Normally what you would do is meet with someone using some kind of out-of-bounds communication. One of the best ways to do this is to exchange public keys in person. That way you can be absolutely sure that the public key came from them. For someone as prolific as Fyodor, his public key has been available for a very long time and is present in a lot of trusted sources: The NMAP project’s website, the official Github mirror, and published in his book both online and in print. For this tutorial, we are setting the trust level and signing it because we know that this public key is valid.  There are alternate ways of verifying trust through the web of trust model, but for this tutorial we’re trusting it because we have multiple independently verifiable sources.

We’ll set the trust level for this to 4. 

vagrant@vagrant:/client_code/pgp$ gpg --edit-key fyodor

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.

pub  dsa1024/1AF6EC5033599B5F

     created: 2005-04-24  expires: never       usage: SC

     trust: marginal      validity: unknown

sub  elg2048/CFAD8512D3C2241C

     created: 2005-04-24  expires: never       usage: E

[ unknown] (1). Fyodor <fyodor@insecure.org>

gpg> trust

pub  dsa1024/1AF6EC5033599B5F

     created: 2005-04-24  expires: never       usage: SC

     trust: marginal      validity: unknown

sub  elg2048/CFAD8512D3C2241C

     created: 2005-04-24  expires: never       usage: E

[ unknown] (1). Fyodor <fyodor@insecure.org>

Please decide how far you trust this user to correctly verify other users' keys

(by looking at passports, checking fingerprints from different sources, etc.)

  1 = I don't know or won't say

  2 = I do NOT trust

  3 = I trust marginally

  4 = I trust fully

  5 = I trust ultimately

  m = back to the main menu

Your decision? 4

pub  dsa1024/1AF6EC5033599B5F

     created: 2005-04-24  expires: never       usage: SC

     trust: full          validity: unknown

sub  elg2048/CFAD8512D3C2241C

     created: 2005-04-24  expires: never       usage: E

[ unknown] (1). Fyodor <fyodor@insecure.org>

Please note that the shown key validity is not necessarily correct

unless you restart the program.

gpg> quit


For the final part we need to sign Fyodor’s key with our own. Here we’ll create a RSA key that will expire in a week. 

vagrant@vagrant:/client_code/pgp$ sudo apt-get install rng-tools # use sudo yum install rng-tools on CentOS/Fedor/Rh types

$sudo rngd -r /dev/urandom

vagrant@vagrant:/client_code/pgp$ gpg --full-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.


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? 4

RSA keys may be between 1024 and 4096 bits long.

What keysize do you want? (3072) 4096

Requested keysize is 4096 bits

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? (0) 7

Key expires at Thu 07 Oct 2021 03:45:24 PM UTC

Is this correct? (y/N) y


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


Real name: ochaun

Email address: ochaun@secureideas.com

Comment: test

You selected this USER-ID:

    "ochaun (test) <ochaun@secureideas.com>"


Change (N)ame, (C)omment, (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 A0ADB966E5E4A5F1 marked as ultimately trusted

gpg: directory '/home/vagrant/.gnupg/openpgp-revocs.d' created

gpg: revocation certificate stored as '/home/vagrant/.gnupg/openpgp-revocs.d/ECB98D2F49131F9F653D793EA0ADB966E5E4A5F1.rev'

public and secret key created and signed.


Note that this key cannot be used for encryption.  You may want to use

the command "--edit-key" to generate a subkey for this purpose.

pub   rsa4096 2021-09-30 [SC] [expires: 2021-10-07]

      ECB98D2F49131F9F653D793EA0ADB966E5E4A5F1

uid                      ochaun (test) <ochaun@secureideas.com>

After that all is left to do is sign. 

vagrant@vagrant:/client_code/pgp$ gpg --sign-key fyodor

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-10-07

pub  dsa1024/1AF6EC5033599B5F

     created: 2005-04-24  expires: never       usage: SC

     trust: full          validity: unknown

sub  elg2048/CFAD8512D3C2241C

     created: 2005-04-24  expires: never       usage: E

[ unknown] (1). Fyodor <fyodor@insecure.org>



pub  dsa1024/1AF6EC5033599B5F

     created: 2005-04-24  expires: never       usage: SC

     trust: full          validity: unknown

 Primary key fingerprint: BB61 D057 C0D7 DCEF E730  996C 1AF6 EC50 3359 9B5F


     Fyodor <fyodor@insecure.org>


Are you sure that you want to sign this key with your

key "ochaun (test) <ochaun@secureideas.com>" (A0ADB966E5E4A5F1)


Really sign? (y/N) y

Now when you use --verify it won’t produce the warning

vagrant@vagrant:/client_code/pgp$ gpg --verify nmap-7.92-win32.zip.asc

gpg: assuming signed data in 'nmap-7.92-win32.zip'

gpg: Signature made Sat 07 Aug 2021 11:59:41 PM UTC

gpg:                using DSA key 436D66AB9A798425FDA0E3F801AF9F036B9355D0

gpg: checking the trustdb

gpg: marginals needed: 3  completes needed: 1  trust model: pgp

gpg: depth: 0  valid:   1  signed:   1  trust: 0-, 0q, 0n, 0m, 0f, 1u

gpg: depth: 1  valid:   1  signed:   1  trust: 0-, 0q, 0n, 0m, 1f, 0u

gpg: depth: 2  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 1f, 0u

gpg: next trustdb check due at 2021-10-07

gpg: Good signature from "Nmap Project Signing Key (http://www.insecure.org/)" [full]

 

Is all of this really necessary?

Sometimes you just really need to be sure. For example, in 2020 you would think the DEFCON 28 cancellation is one elaborate joke. One way you could verify this is legit is to go to a forum post from Dark Tangent and compare the fingerprint in the signature. All you would have to do is follow the same process above with Dark Tangent’s PGP public key on the PGP Global Directory.

Are there alternatives?

Manually downloading signatures and keys for verification can be time consuming. Most of the time this is done in package managers or in linux distributions. Instead of manually checking each time you can do a quick MD5, SHA1, SHA256, or SHA512 hash of a file and verify it against the checksum. For the nmap-7.92-win32.zip checksum, you can find it located at,  https://nmap.org/dist/sigs/nmap-7.92-win32.zip.digest.txt

vagrant@vagrant:/client_code/pgp$ md5sum nmap-7.92-win32.zip

875727768baa62d961f411bb65b79365  nmap-7.92-win32.zip

Key Takeaways

PGP isn’t just useful for encrypting and decrypting email. It is also useful for verifying the authenticity of messages and files, and gives us a way to prove a message came from its original source. Nonrepudiation is essential because you shouldn't blindly trust anything from the internet. In this blog we learned that:

  1. In order to verify PGP signatures you need access to to the sender's public key and a PGP utility program
  2. Signing tells the PGP utility how much you trust the key and you should only sign keys that you have verified independently 
  3. Computing hashes and comparing against a checksum is a quick and easy alternative

Chances are if you're interested in PGP, you're probably interested in encrypting your hard drive. Check out that post for more details and follow us for more privacy focused tutorials. 

Join the professionally evil newsletter