Verify downloaded software with OpenPGP signatures
Checking a download takes three steps. Get the project’s signing key and confirm its fingerprint from a second, trusted source. Use it to verify the signature file. Then compare the file’s hash, if the project signs a checksum list. Below, the same steps are worked through on a real Debian installer image and on GnuPG’s own source code.
Why a checksum alone is not enough
A checksum such as SHA-512 catches a damaged or incomplete download. But if someone has broken into the download server, they can change the file and the checksum next to it. A signature made with the project’s secret key cannot be forged that way. The checks only protect you if you know the right public key, and that is what the fingerprint step is for.
Example 1: a Debian installer image
Debian does not sign each ISO file. Instead, each image folder has checksum files (SHA256SUMS, SHA512SUMS) and a signature for each (SHA256SUMS.sign, SHA512SUMS.sign). As of November 2026 the current release is Debian 13.7.0. The amd64 netinst image is debian-13.7.0-amd64-netinst.iso, in https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/.
1. Download the image and both files
B=https://cdimage.debian.org/debian-cd/current/amd64/iso-cd
curl -fLO $B/debian-13.7.0-amd64-netinst.iso
curl -fLO $B/SHA512SUMS
curl -fLO $B/SHA512SUMS.sign
2. Get the Debian CD signing key and check its fingerprint
The page debian.org/CD/verify lists the keys that have signed recent releases, with fingerprints and download links. The key used for current releases is the “Debian CD signing key” DA87E80D6294BE9B:
curl -fLO https://www.debian.org/CD/key-DA87E80D6294BE9B.txt
gpg --show-keys key-DA87E80D6294BE9B.txt
pub rsa4096 2011-01-05 [SC]
DF9B9C49EAA9298432589D76DA87E80D6294BE9B
uid Debian CD signing key <debian-cd@lists.debian.org>
sub rsa4096 2011-01-05 [E]
47A8EA16451BF5C9B6915C64642A5AC311CD9819
Compare the primary fingerprint with the one on the Debian page: DF9B 9C49 EAA9 2984 3258 9D76 DA87 E80D 6294 BE9B. If they match, import the key:
gpg --import key-DA87E80D6294BE9B.txt
You may see a line such as “64 signatures not checked due to missing keys”. That is harmless: they are certifications from Debian developers whose keys you do not have.
3. Verify the checksum file
gpg --verify SHA512SUMS.sign SHA512SUMS
gpg: Signature made Sat 12 Sep 2026 12:20:46 PM EDT
gpg: using RSA key DF9B9C49EAA9298432589D76DA87E80D6294BE9B
gpg: Good signature from "Debian CD signing key <debian-cd@lists.debian.org>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg: There is no indication that the signature belongs to the owner.
DF9B9C49EAA9298432589D76DA87E80D6294BE9B
“Good signature” together with the fingerprint you just checked is what matters. The WARNING only means you have not certified the key yourself (why).
4. Check the image against the list
sha512sum -c --ignore-missing SHA512SUMS
debian-13.7.0-amd64-netinst.iso: OK
--ignore-missing skips the other images in the list that you did not download. On Windows PowerShell, run Get-FileHash .\debian-13.7.0-amd64-netinst.iso -Algorithm SHA512 and compare the result with the line in SHA512SUMS by eye. Do this only after step 3 has passed.
Already on Debian? Install the debian-keyring package. It includes /usr/share/keyrings/debian-role-keys.pgp, the keyring that holds Debian’s role keys, and you can verify against it directly: gpgv --keyring /usr/share/keyrings/debian-role-keys.pgp SHA512SUMS.sign SHA512SUMS.
Example 2: GnuPG’s own source code
GnuPG signs each release tarball with a detached .sig file. As of November 2026 the current release is 2.5.24.
curl -fLO https://gnupg.org/ftp/gcrypt/gnupg/gnupg-2.5.24.tar.bz2
curl -fLO https://gnupg.org/ftp/gcrypt/gnupg/gnupg-2.5.24.tar.bz2.sig
curl -fLO https://gnupg.org/signature_key.asc
gpg --show-keys signature_key.asc
The file signature_key.asc holds six release keys. Compare each fingerprint with the list on gnupg.org/signature_key.html. The project also publishes the same information as a PDF carrying a qualified digital signature. The two keys that signed 2.5.24 are:
- Werner Koch (dist signing 2020):
6DAA 6E64 A76D 2840 571B 4902 5288 97B8 2640 3ADA - Niibe Yutaka (GnuPG Release Key):
AC8E 115B F73E 2D8D 47FA 9908 E98E 9B2D 19C6 C8BD
gpg --import signature_key.asc
gpg --verify gnupg-2.5.24.tar.bz2.sig gnupg-2.5.24.tar.bz2
gpg: Signature made Wed 23 Sep 2026 07:40:27 AM EDT
gpg: using EDDSA key 6DAA6E64A76D2840571B4902528897B826403ADA
gpg: Good signature from "Werner Koch (dist signing 2020)" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg: There is no indication that the signature belongs to the owner.
6DAA6E64A76D2840571B4902528897B826403ADA
gpg: Signature made Wed 23 Sep 2026 08:40:06 PM EDT
gpg: using EDDSA key AC8E115BF73E2D8D47FA9908E98E9B2D19C6C8BD
gpg: Good signature from "Niibe Yutaka (GnuPG Release Key)" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg: There is no indication that the signature belongs to the owner.
AC8E115BF73E2D8D47FA9908E98E9B2D19C6C8BD
Two good signatures, both from fingerprints on the official list. The tarball is genuine. As an extra check, its SHA-256 hash matches the value on GnuPG’s integrity-check page: bf149d01a2b9fcc0e4589b8ae8697d3d5c557ea48ed95a3fa55dd3b1187e6039. GnuPG’s advice is to do this check with a GnuPG you already trust, such as your distribution’s, and never with the copy you have just downloaded.
Doing it in a script
For automated builds, do not search the output for “Good signature”. Use gpgv with a keyring that holds only the keys you accept:
gpg --dearmor --output gnupg-release-keys.gpg signature_key.asc
gpgv --keyring ./gnupg-release-keys.gpg gnupg-2.5.24.tar.bz2.sig gnupg-2.5.24.tar.bz2
Or pin the exact signer with --assert-signer. GnuPG then exits with 0 only if a valid signature comes from that fingerprint, and with 1 otherwise:
gpg --assert-signer 6DAA6E64A76D2840571B4902528897B826403ADA \
--verify gnupg-2.5.24.tar.bz2.sig gnupg-2.5.24.tar.bz2
Other projects
Most projects follow one of these two patterns: a detached .asc or .sig next to each file, or a signed checksum list. The steps are always the same. Find the fingerprint on the project’s own HTTPS website (ideally confirmed by a second source), verify the signature, then check the hash. On Windows, installers such as Gpg4win also carry a Microsoft code signature. Gpg4win’s download page gives an OpenPGP signature and a SHA-256 checksum as well (details). For package repositories, see APT repository keys.
When verification fails
BAD signature- The file or the checksum list is not what the project signed. Do not open or install it. Delete it, download again from the official site, and verify again. If it still fails, tell the project.
Can't check signature: No public key- You have not imported the signing key. The line “using … key” shows its fingerprint. Get that key from the project and check it, as in step 2.
- Good signature, but from a key you do not recognise
- Treat this as a failure. A valid signature from an unknown key proves nothing. Check the project’s page: projects do change release keys, and GnuPG added new ones in 2025 and 2026.
sha512sum: … FAILED- The image is damaged or incomplete, or it is not the file the list describes. Download it again, and never use an image that fails this check.
[expired]or “This key has expired”- The signature was made with a key that has since expired. Look for the project’s current key and a newer release.
Sources
- Verifying authenticity of Debian images, Debian
- Index of /debian-cd/current/amd64/iso-cd (file names and SHA512SUMS), Debian
- File list of package debian-keyring in trixie, Debian
- Integrity Check, GnuPG
- Signature Key (release signing keys and fingerprints), GnuPG
- Download (gnupg-2.5.24 tarball and signature), GnuPG
- Operational GPG Commands (--verify, --show-keys, gpgv note), The GNU Privacy Guard manual
- Configuration options (--assert-signer), The GNU Privacy Guard manual
- sha512sum(1) manual page, Debian
- Get-FileHash, Microsoft Learn
- Download Gpg4win and Check integrity of Gpg4win packages, Gpg4win