How to Verify Digital Signatures

You want to have very high confidence in two features of a received e-mail message or a downloaded file.

First, the integrity of the data — Is this really the original data, or has it been modified, replaced, or even inserted into the communications channel by an attacker?

Second, the identity of the sender — Is the data really from who it claims to be, or is some attacker trying to masquerade as some legitimate sender of information?

You can answer those questions and have high confidence in the two features if you very carefully verify the digital signature.

The mechanics of verification are simple. The receiver has two pieces of data. The first is the message itself, which can be of any size and format. The second is the digital signature, a small (typically 20 bytes) block of binary data. The receiver's software does two simple cryptographic operations and a comparison:

  1. Calculate the cryptographic hash of the message, typically using SHA-1.
  2. Treat the digital signature as ciphertext and decrypt it with the purported sender's public key, typically using DSA or RSA.
  3. Compare the hash calculated in the first step with the cleartext result of the second step. The signature is good, meaning that you have verified the data integrity and sender authentication, if the two results are identical.

All that is done for you by PGP tools like GNU Privacy Guard (GnuPG). The difficult part that remains is getting the sender's public key. It sounds like it should be easy to get a public key, but it can be difficult to do this correctly.

Validity and Trust

There are two important concepts associated with the public keys of other people and organizations that you will collect on what is called your PGP "public keyring" — validity and trust.

Validity is your confidence that the public key that claims to be Bob's public key really belongs to this Bob fellow. You ran this command and saw the following output:

$ gpg --list-key bob
pub   1024D/62FE4DD1 2001-04-27
uid                  Bob Cromwell <bob.cromwe11@comcast.net>
sub   1024g/B7D9B82C 2001-04-27

However, anyone can use PGP software to generate a public key with any claimed identity! By the way, that looks like my e-mail address but it isn't — I have replaced the L's with the digit "1" so spammers don't scrape my address off this page. But other wise that's the actual command and output copied and pasted into this page.

An example of validity from the physical world would be what a border guard does with your passport when you try to enter a country. They can validate your claimed identity credential by first being familiar with the passports of various countries. Is that small leatherette booklet you presented really a valid passport issued by the nation of Freedonia? If they are not familiar with Freedonian passports, they should have some sort of reference available. Then, does the physical description and photograph seem to be of you? It is a Freedonian passport, but is it your Freedonian passport?

Trust is your confidence that a given person or organization is a careful issuer of credentials. In the physical world, does the Freedonian Foreign Ministry carefully check the identity of applicants for passports? Is a Freedonian passport easier or harder to get than a driver's license or a library card?

Trust in a person or organization means that you are willing to use them as an introducer. You are not going to verify the person's identity, probably it is not practical or even possible for you to really do so. You effectively say, "Good enough for the introducer is good enough for me."

Verifying Key Validity

Let's say that you have downloaded my public key and imported it into your public keyring. The following commands will do this if you have installed GnuPG, you can just copy and paste them into the command line:

$ /tmp
$ wget http://cromwell-intl.com/security/public-key.html
$ gpg --import public-key.html

You can verify that you really have what claims to be my public key:

$ gpg --list-key bob
pub   1024D/62FE4DD1 2001-04-27
uid                  Bob Cromwell <bob.cromwe11@comcast.net>
sub   1024g/B7D9B82C 2001-04-27

You have added some key, but is it really mine? You could check the fingerprint of the key, an MD5 or SHA hash of the public key itself:

$ gpg --fingerprint 62FE4DD1
pub   1024D/62FE4DD1 2001-04-27
      Key fingerprint = 6EBE A241 1131 573C 944E  7FC3 1343 C15E 62FE 4DD1
uid                  Bob Cromwell <bob.cromwe11@comcast.net>
sub   1024g/B7D9B82C 2001-04-27

Now I could tell you that you should expect to see the following fingerprint of my public key:
6EBE A241 1131 573C 944E   7FC3 1343 C15E 62FE 4DD1
However, careful hackers could have modified this page as part of a complex scheme to mislead you about my identity and possibly about the Linux kernel organization's public key.

So what can you do? Since I am a private individual, this is difficult to solve. I could give you my business card if we met in person. My card includes my PGP public key fingerprint. You could ask other people if they knew the true fingerprint of my public key, but chances are next to zero that you will ever meet anyone who can accurately answer that question. You could search for me at public key servers, but all you find is some public key that claims to be mine. It could have been generated and uploaded by anyone.

We need another mechanism....

Using Trust

Let's say that we have done enough work to make you believe the validity of your copy of my public key. We actually met somewhere. Or you tracked me down on the telephone to ask me for my key fingerprint, and you believe that the telephone company is not part of some vast conspiracy to mislead you. Put simply, you believe that you really have my key.

What you do is digitally sign that key on your public keyring. That tells your PGP software "That key is valid." The second command here will show you that my key now has at least two signatures — mine (PGP public keys are X.509 self-signed certificates) and yours.

$ gpg --sign-key 62FE4DD1
....answer the question....
$ gpg --check-sigs 62FE4DD1

Furthermore, let's say that you have decided to trust me in the way defined above. You are willing to use me an an introducer, to accept what I say about which public keys belong to which people and organizations. "Good enough for Bob is good enough for me", you say.

If you decide to do that, you edit the settings on my key to change the trust:

$ gpg --edit-key 62FE4DD1
....use the "trust" command, answer the questions, save the changes....
$ gpg --check-sigs 62FE4DD1

Putting Everything Together

As an example, let's say that you want to build a Linux kernel. You have downloaded the kernel source code archive file and the corresponding digital signature file from http://www.kernel.org/ and now you want to verify the integrity of that data and the identity of its source.

You could start by asking GnuPG to answer your question:

$ gpg --verify linux-release.tar.bz2.sign

That will fail because you do not have the kernel organization's public key. So download it and import it onto your keyring. I have a copy on my site:

$ wget http://cromwell-intl.com/unix/kernel.org-key.html
$ gpg --import kernel.org-key.html
$ gpg --list-keys kernel.org

Let's say that you have not done any of the steps in the above sections to import my public key, or if you did, you have removed it.

You can try the verification step again. This time it will fail differently. You will get a message saying the the signature appears to be good, but it was made with a key you do not necessarily believe to be valid. In other words, the math works but you have no reason to believe that that means anything.

Now, let's say you go back up and do the steps to import, validate, and sign my key, and then you edit your trust in me.

The verification should work now, because through a chain of trust you now have confidence in the validity of the kernel.org key without doing any work to directly verify it:

You can verify that my trusted key was used to sign that copy of the kernel.org key:

$ gpg --check-sigs kernel.org

Now you are finally ready to verify the digital signature. You really want to see something like this:

$ gpg --verify linux-release.tar.bz2.sign
gpg: Signature made Sun Jul 13 18:56:03 2008 EDT using DSA key ID 517D0F0E
gpg: Good signature from "Linux Kernel Archives Verification Key <ftpadmin@kernel.org>"

You certainly hope that you do not see anything like the following! What does it mean? It's hard to say — maybe your download was corrupted, or maybe you downloaded something provided by a hacker!

$ gpg --verify linux-release.tar.bz2.sign
gpg: Signature made Sun Jul 13 18:56:03 2008 EDT using DSA key ID 517D0F0E
gpg: BAD signature from "Linux Kernel Archives Verification Key <ftpadmin@kernel.org>"

No, you will not see those helpful color highlights. Read your output carefully!


Home Unix/Linux Networking Infosec Travel Technical Radio Site Map Contact
Use /bin/vi! Manipulate images with ImageMagick! Hosted on OpenBSD
Hosted on Apache Valid XHTML 1.1! Valid CSS!
© Bob Cromwell Mar 2010. Created with /bin/vi and ImageMagick, hosted on OpenBSD with Apache.    Root password available here, privacy policy here.