Verify with GPG Key

When given a signed payload and an associated signature certificate, you need to verify them in order to maintain integrity. This section guides you on how to verify a signed payload with the GPG Key.

Identify Sign Capability

We start off by identifying the target primary key ID and there are public subkey for signing. This is by using the following command and find your key:

gpg --list-keys --keyid-format LONG

Example:

$ gpg --list-keys --keyid-format LONG
...
---------------------------
pub   rsa4096/F5EF57A0FB4EF0EF 2020-01-10 [C]
      AC51A10307C10B2A4BB1C89AF5EF57A0FB4EF0EF
uid                 [ultimate] "Shotgun" John, Smith <john.smith@company.com>
uid                 [ultimate] "Shotgun" John, Smith (Main ID) <john.smith@email.com>
ssb   rsa4096/66F2E45747AB2C90 2020-01-10 [S] [expires: 2022-01-09]
ssb   rsa4096/9D485C5208D0859F 2020-01-10 [E] [expires: 2022-01-09]
ssb   rsa4096/90939A7DBBFC226D 2020-01-10 [A] [expires: 2022-01-09]
ssb   ed25519/16972F736B59F874 2020-01-10 [S] [expires: 2022-01-09]
ssb   ed25519/D22D6E1FD575E506 2020-01-10 [A] [expires: 2022-01-09]
ssb   cv25519/25252612A403B41C 2020-01-10 [E] [expires: 2022-01-09]

In the example above,

  1. The primary key ID is: AC51A10307C10B2A4BB1C89AF5EF57A0FB4EF0EF. Make sure this is the target primary key you wanted to use for verification.
  2. the sign-capable ("[S]" label) sub-keys are: 66F2E45747AB2C90, and 16972F736B59F874.

Verify Payload With Subkey

Depending on how the payload is signed, gpg offers 2 ways to handle all of them.

Simple Signed Payload

This payload has the an embedded signature within. For this case, all you need is to feed the payload filepath into the --verify command:

$ gpg --verify <path/to/payload>

An generated outcome is as follows:

$ gpg --verify object.txt.gpg 
gpg: Signature made Thu 27 Sep 2020 12:10:08 PM +08
gpg:                using RSA key AC51A10307C10B2A4BB1C89AF5EF57A0FB4EF0EF
gpg: Good signature from ""Shotgun" John, Smith <john.smith@company.com>" [ultimate]

Detached Signature Certificate and Payload

For payload with detached signature certificate, you need to feed the certificate first before the payload. the command would be:

$ gpg --verify <path/to/cert> <path/to/payload>

This will generate the following outcome:

$ gpg --verify object.txt.sig object.txt
gpg: Signature made Thu 27 Sep 2020 12:10:08 PM +08
gpg:                using RSA key AC51A10307C10B2A4BB1C89AF5EF57A0FB4EF0EF
gpg: Good signature from ""Shotgun" John, Smith <john.smith@company.com>" [ultimate]

Error Messages

There are error messages of course. We need to understand each of them and handle them gracefully.

ERROR: BAD Signature

This is an indicator of temperament. It can be caused by:

  1. The payload file got tempered
  2. The signature file got tempered
  3. The object file is not the right file.

To deal with this, you need to communicate with your correspondent about the issue and identify the source of temperament.

# read the signed document
$ cat object.txt.asc
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

This is my message
-----BEGIN PGP SIGNATURE-----

iQIzBAEBCAAdFiEEhDPmxaW4RPhIZkYf3/AJ9CuPZfEFAlusWCwACgkQ3/AJ9CuP
ZfHC8g//dy4lStNOj1PFjW3puTHww6rpnlvmNiZW4/p3s6KebufUs5vuKccm0Skw
kggueRwFDJaAJlQ6prk/ZX9PmYGAHBGGbfojimjKOuyH+hJChwrCr5psHcdBnI+r
vYYpjgzbzfbJZtM90XxgXMsv5wMNn6rilIvathaz/EhkNwFv71xzdmFxo9qqzgc6
93nA5BgxvD6g+ju/wHlGRXyYQr8EzqK05W3zZ0HrsmeHx5JyednGtt72r4ReqY5A
aZZVe382b029gQspo5xOXyTN5bjxG+T4wOj2Crxaz5X8ZiHrH6OZMad7+Gdyylce
vNo3iwOlomSz66RKzr+SRopoMi5h87ssWCmJlFkoUYRmmt3vTXut8yqCpLwiZp1W
BCP0tKA/XSzLEo8BjVe6+9pjFDXsPYIbAVjiPaaHEZDIxsYmdLikAr3mEuBg9cYB
u7dTeKJTFHBUEm0WEGDZ0yV3r9TwHq4PZRdBmpLa08rjvanOgBV7/Q5PqlsACY9E
46FC68npMYCEMM+CcZCpnfOjJkV62+lr5yVtLNosgGL4/AEXBc6CzmkqK2U0IbCi
Za1oz44JzAPfaOF/s8F37gSK0g69IZB6+v3pKXTX0h1W5RzE+lKMwmsOsrX0tvWp
Wq+M2f80Gs8pTQAfXZ/Px93YEpYEQgNWrvfrNq50pKAeCereKuE=
=uTE1
-----END PGP SIGNATURE-----


# verify the document
$ gpg --verify object.txt.asc
gpg: Signature made Thu 27 Sep 2018 12:10:20 PM +08
gpg:                using RSA key 8433E6C5A5B844F84866461FDFF009F42B8F65F1
gpg: Good signature from "Jane (Michael) Smith (Personal Individual Identity) <jane.smith@example.com>" [ultimate]


# temper the document so that it alters the contract contents
$ vi object.txt.asc 
$ cat object.txt.asc 
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

This is Rachel's message
-----BEGIN PGP SIGNATURE-----

iQIzBAEBCAAdFiEEhDPmxaW4RPhIZkYf3/AJ9CuPZfEFAlusWCwACgkQ3/AJ9CuP
ZfHC8g//dy4lStNOj1PFjW3puTHww6rpnlvmNiZW4/p3s6KebufUs5vuKccm0Skw
kggueRwFDJaAJlQ6prk/ZX9PmYGAHBGGbfojimjKOuyH+hJChwrCr5psHcdBnI+r
vYYpjgzbzfbJZtM90XxgXMsv5wMNn6rilIvathaz/EhkNwFv71xzdmFxo9qqzgc6
93nA5BgxvD6g+ju/wHlGRXyYQr8EzqK05W3zZ0HrsmeHx5JyednGtt72r4ReqY5A
aZZVe382b029gQspo5xOXyTN5bjxG+T4wOj2Crxaz5X8ZiHrH6OZMad7+Gdyylce
vNo3iwOlomSz66RKzr+SRopoMi5h87ssWCmJlFkoUYRmmt3vTXut8yqCpLwiZp1W
BCP0tKA/XSzLEo8BjVe6+9pjFDXsPYIbAVjiPaaHEZDIxsYmdLikAr3mEuBg9cYB
u7dTeKJTFHBUEm0WEGDZ0yV3r9TwHq4PZRdBmpLa08rjvanOgBV7/Q5PqlsACY9E
46FC68npMYCEMM+CcZCpnfOjJkV62+lr5yVtLNosgGL4/AEXBc6CzmkqK2U0IbCi
Za1oz44JzAPfaOF/s8F37gSK0g69IZB6+v3pKXTX0h1W5RzE+lKMwmsOsrX0tvWp
Wq+M2f80Gs8pTQAfXZ/Px93YEpYEQgNWrvfrNq50pKAeCereKuE=
=uTE1
-----END PGP SIGNATURE-----


# verify the document again
$ gpg --verify object.txt.asc 
gpg: Signature made Thu 27 Sep 2018 12:10:20 PM +08
gpg:                using RSA key 8433E6C5A5B844F84866461FDFF009F42B8F65F1
gpg: BAD signature from "Jane (Michael) Smith (Personal Individual Identity) <jane.smith@example.com>" [ultimate]

$


ERROR: No Signed Data

This happens when a signature certificate file is given but the payload is missing.

To fix this, supply the payload file path.

gpg --verify object.txt.sig 
gpg: no signed data
gpg: can't hash datafile: No data


ERROR: No GPG Signature Found

This means the payload file you're verifying is not a valid GPG file or not signed.

To fix this, communicate with your correspondent to send a signed payload.

$ gpg --verify ~/Desktop/IMG_20180918_090717.jpg 
gpg: no signature found
gpg: the signature could not be verified.
Please remember that the signature file (.sig or .asc)
should be the first file given on the command line.


WARNING: not a detached signature; file was NOT verified!

This is a warning when you verify an embedded --sign or --clear-sign payload file next to its unsigned version. It serves as a notice telling you that the verification does not include the unsigned version in hand.

To fix this:

  1. Remove/rename the object file next to the signed file and re-verify again.
  2. If the intention was to check the object file integrity, ask your sender to perform --detach-sign instead.

Here's an example:

# check the current directory
$ ls
object.txt  object.txt.asc  object.txt.crt  object.txt.gpg  object.txt.sig

# verify the object
$ gpg --verify object.txt.asc 
gpg: Signature made Thu 27 Sep 2018 12:10:20 PM +08
gpg:                using RSA key 8433E6C5A5B844F84866461FDFF009F42B8F65F1
gpg: Good signature from "Jane (Michael) Smith (Personal Individual Identity) <jane.smith@example.com>" [ultimate]
gpg: WARNING: not a detached signature; file 'object.txt' was NOT verified!

# remove the vanila object file by renaming it
$ mv object.txt object.txt.bak

# check the current directory again. Now, the object.txt is missing
$ ls
object.txt.asc  object.txt.bak  object.txt.crt  object.txt.gpg  object.txt.sig

# verify again
$ gpg --verify object.txt.asc 
gpg: Signature made Thu 27 Sep 2018 12:10:20 PM +08
gpg:                using RSA key 8433E6C5A5B844F84866461FDFF009F42B8F65F1
gpg: Good signature from "Jane (Michael) Smith (Personal Individual Identity) <jane.smith@example.com>" [ultimate]

$

That's all about verifying a signed payload with GPG.