# How to verify the signatures, within GnuPG Certificates, from the command-line.

I found this to be a very specific question, with inadequate documentation elsewhere on the Web, and so I’m writing my own observations on it here. First of all, the reader should know what a certifiicate is, as opposed to just, ‘a public key’. A public key goes together Mathematically with a private key, so that either will decrypt what the other enrcypted, but in such a way that, if the public is made aware of the public key alone, they are unable to derive the private key.

This does not just get used for encryption, but also to sign documents or other electronic assets. In fact, if the RSA algorithm is being used for encryption, it may already be somewhat out-of-date, because many Web sites that have an ‘httpS://’ URL, use TLS by now, instead of SSL, the latter being insecure by today’s knowledge. However, while Diffie-Hellman key exchange is suitable for encryption, creating a shared secret between the server and client, that in turn can be used as a strong, symmetrical key for a connection, the actual verification of Web-sites still uses RSA. But, that’s a bit of an aside comment, because we’re not interested in this posting, in certifying Web-sites with an X.509 certificate. This posting is about ‘GnuPG’, which is an alternative to ‘X.509′.

A certificate is what one obtains, when a public key belonging to one person, together with certain mandatory information, is signed, using the private key of another, so that the public key of the other person can be used to validate that signature. This is important because, if there were only a public and private key, the recipient of a (signed) document would have no way of knowing, whether a public key he’s been given, actually belongs to the correct author. He’d just know, that it’s the public key associated with an arbitrary private key, where the two are supposedly already matched as they should be.

Conversely, if a person wanted to encrypt a document being sent to another, then he’d have no way of knowing, that he’s encrypting it using the correct public key. The person who has the corresponding private key, might not be the intended recipient.

Because of the signature of the public key with another person’s key-pair, that person’s attestation to the fact that it belongs to its rightful owner, can add trust in the public key, for the recipient of a signed document, or the sender of a document to be encrypted, the latter so that only the holder of the correct private key will be able to decrypt it.

So, it can happen to users of GnuPG, that they’ve been using GUIs such as ‘Kleopatra’ or ‘KGPG’, that these GUIs have not displayed any messages, but that they’d like to verify the signatures of their public keys, belonging to other people anyway. And from the command-line, there is a way to do that…

(Updated 5/24/2020, 8h35 … )

(As of 17h30: )

The way this gets done is, that the user types in the command:


$gpg --check-sigs [Key ID]   In order for this to work, all the required keys must already be in a user’s GnuPG keyring, and the ‘Key ID’ above, would be the key’s, of which the signatures by other keys is to be checked. ‘Key ID’ can also be omitted, in which case all the keys in the keyring are checked. The output that one obtains should be something like this:  dirk@Phosphene:~$ gpg --check-sigs 586A6C0052A087C0
pub   rsa4096 2017-06-11 [SCE]
D96EBD7CB547A86B1864C94D586A6C0052A087C0
uid           [ultimate] Dirk Mittler (4096-bit) <xxxxxx@sympatico.ca>
sig!3        586A6C0052A087C0 2017-06-11  Dirk Mittler (4096-bit) <xxxxxx@sympatico.ca>
sig!3        586A6C0052A087C0 2017-06-11  Dirk Mittler (4096-bit) <xxxxxx@sympatico.ca>

gpg: 3 good signatures
dirk@Phosphene:~$gpg --check-sigs 5C71A56990EF8FE0 pub rsa2048 2015-01-27 [SCEA] EB3545C5AA18EF5C9274C8DC5C71A56990EF8FE0 sig! 5C71A56990EF8FE0 2015-01-27 "admin@dirkmittler.homeip.net" <admin@dirkmittler.homeip.net> uid [ultimate] "admin@dirkmittler.homeip.net" <admin@dirkmittler.homeip.net> sig! 5C71A56990EF8FE0 2015-01-27 "admin@dirkmittler.homeip.net" <admin@dirkmittler.homeip.net> sig! 3983B0DEE7C80D1E 2015-01-29 Dirk Mittler (Main email Key) <xxxxxx@sympatico.ca> sub rsa2048 2015-01-27 [SCEA] sig! 5C71A56990EF8FE0 2015-01-31 "admin@dirkmittler.homeip.net" <admin@dirkmittler.homeip.net> gpg: 4 good signatures gpg: 1 signature not checked due to a missing key dirk@Phosphene:~$



There’s a caveat to this. By default, GnuPG only gives messages for keys that it can verify, because the keys which have added their signatures to the certificate, are also in the keyring. What this means in practice is, that the user must import the Signor’s public key first, at which point in time it is Not Trusted. Only then, can he find the original Key ID, and then, verify all the signatures it has. Then, if suitably reassured, the user still needs to give the command, to Trust the original key in question.

In the output above, the keyword ‘sig’ can be followed immediately by a ‘!’, which means that the signature is valid, by a ‘-‘, which means that a signature is verifiably invalid, or by a ‘%’, which means that an error has occurred, perhaps due to an unrecognized algorithm having been used. I don’t know what the ‘3’ means, that sometimes follows ‘!’. (:1)

When Linux users run a GUI, what it will tend to do is give such commands invisibly in the background, and to parse the output from those commands as best the GUI application can.

Because I have run the command without a Key ID, and the output for all the keys, has shown no verifiable, invalid signatures, I have no reason to conclude, that the GUI would fail to indicate anything, if such examples had been found. Presumably, the policy of the GUI matches that of the command-line: Show no output, until the signature is provably invalid.

There’s a major weakness to this policy: A malicious user could ‘simply make up’ a Key ID, and craft it into a (forged) certificate. Neither the GUI, nor anything that the recipient can run from the command-line, will be able to distinguish this Key ID, from a valid one, that for some reason just happens, not to be on the key-server. But the presence of the Key ID can give the recipient some false sense of security.

AFAIK, The GUI-application will show such Key IDs, with no identity beside them, since it’s the Signor’s certificate in the keyring, that would provide such identity information. Also, all such Key IDs need to have an actual signature block. But, if the signature can never be verified, a supposed malicious user can just fill that with pseudo-random bits.

But what this also means is, that if the user wants signature verification, the thing to do would be, to open whatever message-box his GUI shows him, to where the signors of a cert are listed, and then to download the corresponding, ‘Key IDs’. The problem here would be, that there are also ~Fingerprints~ associated with each key, that have more characters, and which are not the Key ID. The difference is the fact that the Key ID was designed to be looked up in a database, and to retrieve the key in question efficiently… (:2)

dirk@Phosphene:~$gpg --list-sigs 586A6C0052A087C0 pub rsa4096 2017-06-11 [SCE] D96EBD7CB547A86B1864C94D586A6C0052A087C0 uid [ultimate] Dirk Mittler (4096-bit) <xxxxxx@sympatico.ca> sig 3 586A6C0052A087C0 2017-06-11 Dirk Mittler (4096-bit) <xxxxxx@sympatico.ca> sig 5C71A56990EF8FE0 2017-06-14 "admin@dirkmittler.homeip.net" <admin@dirkmittler.homeip.net> sig 3 586A6C0052A087C0 2017-06-11 Dirk Mittler (4096-bit) <xxxxxx@sympatico.ca> dirk@Phosphene:~$ 


Only after the Key with that ID has either been downloaded from the key-server, or added from a file, can GnuPG actually test, whether it did in fact sign the key of concern.

What the ‘--list-sigs‘ command-line option would do differently from the ‘--check-sigs‘ option, is actually to list the Key IDs, for which there is no public key in the local computer’s keyring, but with ‘[User ID not found]‘ as ID information. In my example above, it was already in the keyring.

(Update 5/23/2020, 22h45: )

1:)

I have a hunch as to what that digit (3) may mean: That the dates are out of order. In general, the commands list signatures and other articles, in the order they were appended to the certificate. It’s not possible that they were added on: 2017-06-11, 2017-06-14, 2017-06-11 … In that order. The only way to explain that they are listed that way would be, to suggest that a program malfunctioned somewhere, when it was applying them.

The fact that they are like that, does not make any signature invalid cryptographically. It just means, that some curious error has also crept in.

Also, I believe that software is supposed to block a request by the user, to sign a certificate more than once, with the same cert of his own, if nothing has changed in the cert he’s trying to sign – hence the order listed is the correct one.

Also, it seems that I applied ‘Ultimate Trust’ to each certificate, on 2015-01-27, and on 2017-06-11, and the way GnuPG records that is, to write the datum in, in a non-secure way, but then immediately to sign the changes. Therefore, Once a user has given Ultimate Trust, for a cert to authenticate a given email address, This leaves a permanent record.

(Update 5/24/2020, 7h40: )

I dimly seem to recall the night that I created that cert on the computer I had named ‘Plato’ – all the way back in 2017. Something wasn’t working, in that the cert was not being recognized by the ‘Enigmail’ Thunderbird Extension. I had applied Ultimate Trust. Because I had read somewhere on the Web that doing so might solve such a problem, I next tried to self-sign the cert that I just created, but without resolving the issue. Next, I tried to counter-sign, but again without causing the cert to be used by Thunderbird. Then, I self-signed the cert again. I was trying to force the software to do something that it didn’t want to do. But at some later point, the result was that Thunderbird was able to use the cert.

Presently, my best guess as to what the problem might have been, would be, that a user needs to have a default key set up, in order to set the Trust Level of a cert, because, as I just described in this posting, GnuPG needs to sign the fact that the Trust Level has been changed. What key to sign that with? The default key.

When people perform these operations within Thunderbird – with the Enigmail Extension – Thunderbird has its own, local way of determining what the default key is. But if somebody is using ‘Kleopatra’ or ‘KGPG’, then this needs to be set.

I do recall that at a later point in time, I set the GPG default key, using ‘KGPG’, because ‘Kleopatra’ didn’t seem to offer the operation. Well, I might have done so on 2017-06-14, thereby completing an operation which I had first attempted on 2017-06-11. At that point, GnuPG would have had two dates to work with:

1. The date on which I first tried to set the Trust Level, and
2. The date on which I set the default key.

Apparently, one date was stamped onto the self-signatures, while the other was stamped on the counter-signature.

It’s common that I leave my computers running between sessions like that, for weeks or even months at a time. Various software could be caching an erroneous state for that long.

(Update 5/24/2020, 8h35: )

2:)

As it happens, the Key ID is computed either, as the least-significant 32 bits, or the least-significant 64 bits, of the Key Fingerprint. Which gets used depends on the application, but in today’s world, the use of 32-bit Key IDs is strongly discouraged, as their ID-collisions have become commonplace.

One problem with the version of ‘Kleopatra’ I have installed, at least, is that it still uses 32-bit Key IDs. But, using ‘KGPG’, I did set a 64-bit Default Key ID. What this does, is to make it impossible for Kleopatra afterwards, either to set its own Default Key, or to Change Owner Trust.

Dirk