20

I am trying to get a better understanding of what is going on with gpg.

If you have a file and sign it: gpg --sign file.txt

you can verify it with: gpg --verify file.txt.gpg

when you get a successful output: gpg: Signature made...

But when you sign AND encrypt a file: gpg --encrypt --sign -r test@email.com file.txt

and then run --verify on the encrypted file I get: gpg: verify signatures failed: Unexpected error

I know that I can just call --decrypt on the file and it will verify and decrypt it, but what if I want to verify only?

Eric Stermer
  • 959
  • 1
  • 12
  • 23

4 Answers4

27

I figured out the answer to this and then some. So I am going to add some additional information for clarity.

First of all, I realize based on the last line to this answer that gpg uses SIGN THEN ENCRYPT. Which means calling --verify or any variation to verify on an encrypted file will just output gpg: verify signatures failed: Unexpected error. This happens because the signature is "hidden" in encryption, so when you try to call --verify on the file, it will not see a signature.

Secondly, the --decrypt flag will both decrypt the file AND if the file is signed, verify it too.

Here is what --decrypt is doing. It looks at your default secret keyring secring.kbx in ~/.gnupg to use a secret key for decrypting the file. Then after it is decrypted, it looks at your default public keyring pubring.kbx in the folder ~/.gnupg and tries to verify the signature on the file, if it has one.

  • If it has no signature, it will just decrypt the file.

  • If it has a signature, but you don't have the public key, it will decrypt the file but it will fail to verify the signature.

  • If it has a signature and you have the public key, it will decrypt and verify.

With that said, there is no reason to verify a signed file BEFORE decrypting it.

Thirdly, as an added bonus, you can also specify a keyring you want to use for decrypting and verification. Say you want to use a temporary keyring to verify signatures or for what ever reason you want a temporary keyring to decrypt the message too.

You can specify the keyrings for --decrypt to use with the following command:

gpg --secret-keyring path/to/temp/secring.kbx --keyring path/to/temp/pubring.kbx --decrypt file.txt.gpg

This command will look for the secret ring and public ring at the specified paths in order to use those rings for decryption and verification instead of the default rings found in ~/.gnupg. Want to use a default ring with a temp ring? Just omit the flag and path to the ring you want defaulted.

All in all, for encrypted and signed files, if you want to decrypt and verify that file, you need to make sure that the private key for decryption is in your secret keyring and the public key for verification is in your public keyring.

Alexander Kjäll
  • 4,246
  • 3
  • 33
  • 57
Eric Stermer
  • 959
  • 1
  • 12
  • 23
  • 1
    Appreciate your answer. But to point it out, even if you don't have the public key, gpg will still try to verify the signature and fail with a non-zero exit code. – Cyker May 22 '20 at 07:59
  • 1
    *If it has a signature, but you don't have the private key,...* should be corrected to *If it has a signature, but you don't have the public key,...* – Shuzheng Jun 09 '20 at 08:04
  • This answer looks a bit dangerous. While it states correctly that a signed encrypted file will also be verified as a side effect, what about an unsigned encrypted file? The verification phase will be silently skipped and an unverified file will be used, right? – Pavel Šimerda Dec 09 '21 at 13:49
4

One thing to understand about GPG encrypt & sign, which isn't very well explained, is that the signature can only be verified by the recipient.

Suppose Alice encrypts a file to send to Bob. She will encrypt with Bob's public key, and sign with her private key.

gpg --output encrypted.gpg --recipient B0B0000000000000000000000000000000000000 --armor --sign --default-key A11CE00000000000000000000000000000000000 --encrypt file-to-encrypt.txt

There's no way now for Alice, or anyone who does not have Bob's private key, to verify the signature.

Now Bob will decrypt the file. If it is signed, he'll see information about the signature in the output:

$ gpg --decrypt encrypted.gpg > decrypted.txt
gpg: encrypted with 2048-bit RSA key, ID D83A4C12B3840EBA, created 2020-09-24
      "Alice <alice@example.com>"
gpg: Signature made 09/28/20 13:16:47 Eastern Daylight Time
gpg:                using RSA key A11CE00000000000000000000000000000000000 
gpg: Good signature from "Alice <alice@example.com>" [ultimate]

Note the Signature made and Good signature lines in the output.

Kip
  • 107,154
  • 87
  • 232
  • 265
  • A signature can be verified by anyone who has access to the public key. That's the whole point of public key infrastructure. A private key can sign, a public key can encrypt. The file can only be decrypted by the person owning the private key corresponding to the public key with which the file was encrypted. With GnuPG if the file is first signed then encrypted obviously it's a matter of sequence what can be done by whom. If you need to decrypt the file first then you need to own the private key, and only after that is it possible to verify the signature with the sender's public key. – Thomas Seeling Apr 18 '23 at 14:18
1

I know I come years too late.

You know the --decrypt operation of gpg which in this case "decrypts and verifies" the message. You say that well in your own answer and you explain well about the keys needed.

To confirm the two step procedure, one can do one step by

gpg -vi  --output signed.gpg    --unwrap  signed_and_encoded.gpg 

which does the first step, i.e., decrypting. The produced file is now decoded and contains the signature.

This shows that the product of gpg --sign --encrypt file cannot be verified without decrypting, but can be decrypted without (yet) verifying. The decrypted (--unwrapped) file can be later verified (and displayed) by gpg -d, for which only the public key of the sender is needed.

More and link to docs can be found in my answer here

minorChaos
  • 101
  • 7
  • This works, and is an interesting point, but emits the warning: `gpg: WARNING: no command supplied. Trying to guess what you mean ...` Do you know which command should be used? – Max Murphy Sep 02 '23 at 08:10
  • @Max, 1. May differ for various version, so one has to take care. 2. It is not document here in Ubuntu, so one has to take care 3. on inet, it says it is a command, which means it should not complain (for that particular version) 4. Here locally, adding `-d` in front of file does hush the warning but does not disturb the --unwrap action. Test the output file by `gpg` on your machine, if it still contains the signature: `gpg: Good signature from "tests...`. Take care. – minorChaos Sep 02 '23 at 09:43
0
$ gpg --encrypt --sign -r test@email.com file.txt

After file.txt.gpg generated, try the command below:

$ gpg -d file.txt.gpg

or just execute:

$ gpg file.txt.gpg
h2appy
  • 199
  • 1
  • 4