UNIX / Linux PGP TarBall File Signature Keys Verification

I‘ve downloaded open-source software from the Internet. The download server also provided me the PGP signature file. How do I verify that signature (file.tar.gz.asc) file against downloaded software release (software.version.tar.gz) under Linux / UNIX operating systems? How can I verify PGP signature of downloaded software on Linux / Unix?

PGP is an acronym for Pretty Good Privacy. It provides cryptographic privacy and authentication. PGP is often used for encrypting and decrypting e-mails and files. We can use the PGP signature of downloaded software from the Internet too. For all FOSS based project, you should download the PGP signatures and MD5/SHA hashes and verify them before using them. Linux and many other UNIX like operating systems can use The GNU Privacy Guard. However, any OpenPGP-compliant program should work successfully with software. The following instructions assume that you are using the GNU Privacy Guard.
Tutorial details
Difficulty Intermediate (rss)
Root privileges No
Requirements gpg command on Linux or Unix
Time 2m

Step 1. Download tar ball / software along with PGP key for verification

For example, purpose you will download nginx web server and verify the same with PGP. Use the wget command to grab latest version:
$ cd /tmp
$ wget http://nginx.org/download/nginx-1.18.0.tar.gz
$ wget https://nginx.org/download/nginx-1.18.0.tar.gz.asc

Let us list files using the ls command, enter:
$ ls -l
Sample outputs:

total 620
-rw-rw-r-- 1 vivek vivek 1039530 Apr 21 20:03 nginx-1.18.0.tar.gz
-rw-rw-r-- 1 vivek vivek     455 Apr 21 20:03 nginx-1.18.0.tar.gz.asc

Step 2. Checking PGP signatures / verification

Type the following gpg command:
$ gpg nginx-1.18.0.tar.gz.asc
## OR ##
$ gpg --with-fingerprint nginx-1.18.0.tar.gz.asc

Sample outputs:

gpg: WARNING: no command supplied.  Trying to guess what you mean ...
gpg: assuming signed data in 'nginx-1.18.0.tar.gz'
gpg: Signature made Tuesday 21 April 2020 07:43:35 PM IST
gpg:                using RSA key 520A9993A1C052F8
gpg: Can't check signature: No public key

However, the gpg command failed to check the signature as we don’t have the author’s public key 520A9993A1C052F8 in our local Linux / Unix server or workstation. Hence, we need to grab the public key from a key server (such as pgpkeys.mit.edu) or download it from the author’s web site.

Step 3. Linux or Unix command to grab the public key from a key server

The syntax is as follows:

gpg --recv-key <publicKey>
## we can also get keys from speifici key server ##
gpg --keyserver pgpkeys.mit.edu --recv-key <publicKey>

Try to grab the public key A524C53E, enter:
$ gpg --recv-key 520A9993A1C052F8
$ gpg --verbose --recv-key 520A9993A1C052F8

gpg: data source: http://hkps.pool.sks-keyservers.net:11371
gpg: armor header: Version: SKS 1.1.6
gpg: armor header: Comment: Hostname: sks.pod02.fleetstreetops.com
gpg: key 520A9993A1C052F8: number of dropped non-self-signatures: 9
gpg: pub  rsa2048/520A9993A1C052F8 2011-11-27  Maxim Dounin <mdounin@mdounin.ru>
gpg: using pgp trust model
gpg: key 520A9993A1C052F8: public key "Maxim Dounin <mdounin@mdounin.ru>" imported
gpg: Total number processed: 1
gpg:               imported: 1

As you can see, Maxim Dounin <mdounin@mdounin.ru> is listed on the Nginx project site along with his keys:

Step 4. Verify PGP Signature of Downloaded Nginx Software on Linux / Unix

Now, try to verify the software signature again as follows:
$ gpg --verify nginx-1.18.0.tar.gz.asc nginx-1.18.0.tar.gz
You should see outputs as follows:

gpg: Signature made Tuesday 21 April 2020 07:43:35 PM IST
gpg:                using RSA key 520A9993A1C052F8
gpg: Good signature from "Maxim Dounin <mdounin@mdounin.ru>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: B0F4 2533 73F8 F6F5 10D4  2178 520A 9993 A1C0 52F8

Step 5. Command to grab the public key from a web server

Again, use the wget command to grab the public key from a web server:
$ wget https://nginx.org/keys/mdounin.key
Import the key from mdounin.key file, enter:
$ gpg --import mdounin.key

gpg: key 520A9993A1C052F8: 2 signatures not checked due to missing keys
gpg: key 520A9993A1C052F8: public key "Maxim Dounin <mdounin@mdounin.ru>" imported
gpg: Total number processed: 1
gpg:               imported: 1
gpg: marginals needed: 3  completes needed: 1  trust model: pgp
gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u

Now, try to verify the software signature again using the gpg keys:
$ gpg gpg --verify nginx-1.18.0.tar.gz.asc nginx-1.18.0.tar.gz
The signature is good, but you don’t trust this PGP key. In other words, the file has not tampered. However, you need to additionally verify that key 520A9993A1C052F8 was created by the real Nginx author named Maxim Dounin <mdounin@mdounin.ru> and not by someone else.

So, how do I build trust and mark Maxim Dounin’s PGP key as trusted?

This is a little complicated as you never met Maxim Dounin <mdounin@mdounin.ru> face to face. To vouch for the key’s authenticity, you can do so by signing it with your own private key and mailing it back to its owner. This is a simple and easy way to build a trust relationship. Another quick option is to use the following command:
gpg --edit-key {user@example.com} trust
For example:
$ gpg --edit-key mdounin@mdounin.ru trust

WARNING: Do not trust keys blindly to get rid of the warnings. For downloaded software verification, you don’t need to set up a web of trust. The following example is just for demonstration purposes as I never met the author/people behind Nginx or vouch for him.

gpg (GnuPG) 2.2.19; Copyright (C) 2019 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.


pub  rsa2048/520A9993A1C052F8
     created: 2011-11-27  expires: never       usage: SC  
     trust: unknown       validity: unknown
sub  rsa2048/57A82F1DD345AB09
     created: 2011-11-27  expires: never       usage: E   
[ unknown] (1). Maxim Dounin <mdounin@mdounin.ru>

pub  rsa2048/520A9993A1C052F8
     created: 2011-11-27  expires: never       usage: SC  
     trust: unknown       validity: unknown
sub  rsa2048/57A82F1DD345AB09
     created: 2011-11-27  expires: never       usage: E   
[ unknown] (1). Maxim Dounin <mdounin@mdounin.ru>

Please decide how far you trust this user to correctly verify other users' keys
(by looking at passports, checking fingerprints from different sources, etc.)

  1 = I don't know or won't say
  2 = I do NOT trust
  3 = I trust marginally
  4 = I trust fully
  5 = I trust ultimately
  m = back to the main menu

Your decision? 5
Do you really want to set this key to ultimate trust? (y/N) y

pub  rsa2048/520A9993A1C052F8
     created: 2011-11-27  expires: never       usage: SC  
     trust: ultimate      validity: unknown
sub  rsa2048/57A82F1DD345AB09
     created: 2011-11-27  expires: never       usage: E   
[ unknown] (1). Maxim Dounin <mdounin@mdounin.ru>
Please note that the shown key validity is not necessarily correct
unless you restart the program.

gpg> q

Now, try to verify the software signature again:
$ gpg --verify nginx-1.18.0.tar.gz.asc nginx-1.18.0.tar.gz

gpg: Signature made Tuesday 21 April 2020 07:43:35 PM IST
gpg:                using RSA key 520A9993A1C052F8
gpg: checking the trustdb
gpg: marginals needed: 3  completes needed: 1  trust model: pgp
gpg: depth: 0  valid:   2  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 2u
gpg: Good signature from "Maxim Dounin <mdounin@mdounin.ru>" [ultimate]

Since, you have entered the web of trust, you should not see any warning message on screen.

How do I delete “Maxim Dounin <mdounin@mdounin.ru>” key?

The syntax is as follows to list and delete unwated keys:
$ gpg --list-key
$ gpg --delete-keys B0F4253373F8F6F510D42178520A9993A1C052F8
## or ##
$ gpg --delete-keys 520A9993A1C052F8

Conclusion

In this quick tutorial, you learned about PGP and how to verify the PGP signature of downloaded software from the Internet under Linux or Unix-like systems. See following resources for further information:


🐧 Please support my work on Patreon or with a donation.
🐧 Get the latest tutorials on Linux, Open Source & DevOps via:
CategoryList of Unix and Linux commands
File Managementcat
FirewallAlpine Awall CentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Network Utilitiesdig host ip nmap
OpenVPNCentOS 7 CentOS 8 Debian 10 Debian 8/9 Ubuntu 18.04 Ubuntu 20.04
Package Managerapk apt
Processes Managementbg chroot cron disown fg jobs killall kill pidof pstree pwdx time
Searchinggrep whereis which
User Informationgroups id lastcomm last lid/libuser-lid logname members users whoami who w
WireGuard VPNAlpine CentOS 8 Debian 10 Firewall Ubuntu 20.04
6 comments… add one
  • Philippe Petrinko Apr 14, 2010 @ 13:00

    Thanks Vivek, I appreciate it.

  • slava Apr 22, 2011 @ 7:34

    Thank you very match !
    I had to check nginx.

  • person May 25, 2014 @ 16:56

    The last step where you type
    gpg –edit-key igor@sysoev.ru trust
    and then enter 5 to indicate ultimate trust is garbage in, garbage out. A user should *NEVER* do this command not understanding the effects and should never do so if they don’t completely trust this person, Sure it will get rid of the warning message, but the warning message is doing what it should. At the same time, it does still check that the sig is good even with ther warning message.

    • Zach Jul 21, 2015 @ 2:16

      This is absolutely correct. Do tell gpg that you trust a signature unless you have a good reason to actually trust the signature (e.g. actually meeting the owner face to face and verifying their identity and their key). I sincerly hope that the owner of this page edits the information above to reflect how the Web of Trust actually works. The sort of behavior recommended here is an excellent way to destroy the web of trust.

  • Kozaki Dec 22, 2015 @ 16:35

    Nice! But, since (quoting Wayne Pollock) « Gpg will tell you when you verify a signature that the signature is good (or bad) » it misses the *Bad signature* scenario like:

    $ gpg syslinux-6.03.tar.sign
    gpg: Signature made Mon Oct  6 16:32:29 2014 UTC using RSA key ID 58F7ABFE
    gpg: BAD signature from "H. Peter Anvin (kernel.org file signing key) " [unknown]
    

    Also some GPG signed files are not playing it 100 franckly. For example:

    $ gpg --verify syslinux-6.03.tar.sign 
    gpg: no signed data
    gpg: can't hash datafile: No data
    
    $ gpg syslinux-6.03.tar.sign 
    Detached signature.
    Please enter name of data file: syslinux-6.03.tar.gz 
    gpg: Signature made Mon Oct  6 16:32:29 2014 UTC using RSA key ID 58F7ABFE
    
  • Netaji Sep 30, 2020 @ 7:30

    I was looking to verify the PGP key against downloaded software on my Linux box using the GNU Privacy Guard and other OpenPGP-compliant program. This was a wonderful guide. :)

Leave a Reply

Your email address will not be published. Required fields are marked *

Use HTML <pre>...</pre> for code samples. Problem posting comment? Email me @ webmaster@cyberciti.biz