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:
- .asc file, or PGP signature
- The author’s verified public key
- 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 -----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:
- In order to verify PGP signatures you need access to to the sender's public key and a PGP utility program
- Signing tells the PGP utility how much you trust the key and you should only sign keys that you have verified independently
- 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.