Hex dump of Gibe-F worm.

How to Verify Digital Signatures

Verifying Digital Signatures

Digital signatures can provide two aspects of information security. Let's say you have received an e-mail message, or downloaded a data file or program. Or you are going to send that message or provide that file for download for others. Either way, the recipient needs to have very high confidence in two features of that data:

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?

Also see:
How Browsers Use HTTPS and TLS

You can answer those questions and have high confidence in those two features of authenticated messages, making them safe documents 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, using SHA-2-256 or SHA-2-512.
  2. Treat the digital signature as ciphertext and decrypt it with the purported sender's public key, typically using RSA or ECC or DSA or ECDSA.
  3. Compare the hash calculated in the first step with the cleartext result of the second step. If those two results are identical, then the signature is good, meaning that you have verified the data integrity and sender authentication.

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

You collect the public keys of other people and organizations on what is called your "public keyring." There are two important concepts associated with those public keys on your 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:

$ gpg2 --list-key bob
pub   4096R/41E1A929 2015-04-12
uid                  Bob Cromwell <bob.cromwe11@comcast.net>
sub   4096R/C6E07606 2015-04-12

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 otherwise 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:

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

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

$ gpg2 --list-key bob
pub   4096R/41E1A929 2015-04-12
uid                  Bob Cromwell <bob.cromwe11@comcast.net>
sub   4096R/C6E07606 2015-04-12

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

$ gpg2 --fingerprint 41E1A929
pub   rsa4096/41E1A929 2015-04-12 [SC]
      Key fingerprint = 6E6E 1DF0 C381 9172 55B4  AC00 8344 6EEA 41E1 A929
uid         [ultimate] Bob Cromwell <bob.cromwe11@comcast.net>
sub   rsa4096/C6E07606 2015-04-12 [E]

Now I could tell you that you should expect to see the following fingerprint of my public key:
6E6E 1DF0 C381 9172 55B4  AC00 8344 6EEA 41E1 A929
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.

$ gpg2 --sign-key 41E1A929
....answer the question....
$ gpg2 --check-sigs 41E1A929

Sometimes --check-sigs produces a very minor warning of the form:
7 signatures not checked due to missing keys
Don't panic! That just means that the key you received has also been signed by other people. You don't have their public keys so you can't verify their signatures. There's nothing at all bad or ominous about that. Imagine that you have asked someone for their identity papers, wanting to see their national passport. They might respond, "Here is my passport, and my driver's license, and my work ID, and my library card, and my Ralph's supermarket loyalty card, and ..." None of those should count against them! You check the passport, for which you understand the issues of validity and trust, and can safely ignore the rest.

Furthermore, let's say that you have decided to trust me in the way defined above. You are willing to use me as 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:

$ gpg2 --edit-key 41E1A929
....use the "trust" command,
	answer the questions,
	save the changes....
$ gpg2 --check-sigs 41E1A929

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 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:

$ gpg2 --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.

$ gpg2 --keyserver subkeys.pgp.net --recv-keys 6092693E

You can try the verification step again. This time it will fail differently. You will get a message saying that 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.

The kernel.org page on digital signatures shows that the key's fingerprint should be:
647F 2865 4894 E3BD 4571   99BE 38DB BDC8 6092 693E
If that is what you see, you can now sign your copy of that key:

$ gpg2 --sign-key 6092693E
....answer the question....
$ gpg2 --check-sigs 6092693E

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

$ gpg2 --verify linux-release.tar.bz2.sign
gpg2: Signature made Sun, 16 Dec 2018 21:45:46 +0000 using RSA key ID 6092693E
gpg2: Good signature from "Greg Kroah-Hartman (Linux kernel stable release signing key) <greg@kroah.com>"

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!

$ gpg2 --verify linux-release.tar.bz2.sign
gpg2: Signature made Sun, 16 Dec 2018 21:45:46 +0000 using RSA key ID 6092693E
gpg2: BAD signature from "Greg Kroah-Hartman (Linux kernel stable release signing key) <greg@kroah.com>"

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

Also see: