Skip to content
Français
Account: not signed in, sync available My learning
Select theme
Français

Check the integrity of a file: checksums and GPG signatures

By updated

Improve this page

A downloaded file can be corrupted during the transfer, or replaced by an attacker. Checking its integrity is a basic reflex in Linux administration: before installing a tool, restoring a backup or deploying a critical configuration, you make sure the file is exactly the one expected.

Two levels of checking coexist, and this guide tells them apart: the checksum, which detects an alteration, and the GPG signature, which proves the origin. Every output was measured on Debian 13 (coreutils 9.7, GnuPG 2.4.7).

What you will learn

  • Generate the sha256 checksum of a file with sha256sum
  • Check a file against a checksum file provided by the source
  • Understand the differences between md5, sha1, sha256 and sha512
  • Compare two files by their hash to check that they are identical
  • Verify a detached GPG signature (.sig or .asc)
  • Import a public GPG key from a key server or a URL

Integrity vs authenticity: two different levels

These two checks do not answer the same question. Integrity tells whether the file changed since the checksum was computed; authenticity tells who produced it. The table sums up what each one brings and what it protects against.

CheckWhat is checkedToolProtects against
IntegrityThe file has not been alteredsha256sum -cNetwork corruption, transfer error
AuthenticityThe file really comes from the expected authorgpg --verifyMalicious replacement, MITM attack

A checksum alone does not prove authenticity: if an attacker replaces the file and the checksum on a compromised site, the sha256 check still passes. For authenticity, only a GPG signature, verified with a key obtained through an independent channel, gives a real guarantee.


sha256sum: check integrity

A hash (or checksum) is a fixed-size value computed from the content of a file: a single modified byte gives a completely different checksum. sha256sum computes the SHA-256 checksum, 64 hexadecimal characters, and can also compare a file with a published checksum.

Generate the checksum of a file

To reproduce the outputs of this section, create a small working file with fixed content: its checksum will be the same on your machine as on the measurement machine, so you can check your result at a glance.

Terminal window
printf 'sauvegarde du 29 septembre 2026\n' > archive.txt
sha256sum archive.txt
5522a2b250443947ae82340763670f86b15b97b120eadade6754a030b46cc0bd archive.txt

Redirect this output to a file to keep the reference checksum: sha256sum archive.txt > archive.txt.sha256. It is exactly the format that projects publish, one line "hash, space, file name".

Check against a provided checksum

Most serious projects publish a .sha256 or SHA256SUMS file next to their archives. The -c (check) option takes this checksum file as argument, not the archive: it recomputes the checksum of each listed file and compares it with the published value.

Terminal window
sha256sum -c archive.txt.sha256
archive.txt: OK

If the file has been altered, even by a single character, the check fails and sha256sum exits with code 1, which lets you stop a script:

archive.txt: FAILED
sha256sum: WARNING: 1 computed checksum did NOT match

The separator between the hash and the name is tolerant: two spaces, a single one, or a space followed by an asterisk (the binary-mode marker, the one used in Ubuntu's files) are all accepted. On the other hand, a file that holds only the hash, without a name, is rejected with no properly formatted checksum lines found. Many projects publish this format anyway: rebuild the line yourself.

Terminal window
echo "$(cat project-1.0.tar.gz.sha256) project-1.0.tar.gz" | sha256sum -c

Check from a multi-entry SHA256SUMS file

Distributions often publish a single file for every image of a release. You downloaded only one: sha256sum -c checks that one, but reports each missing one with FAILED open or read and exits with code 1, which makes a script fail. The --ignore-missing option skips the missing files and only returns 0 if the present ones are correct.

Terminal window
sha256sum -c --ignore-missing SHA256SUMS
archive.txt: OK

Without the option, the same command prints the OK line, then absent.iso: FAILED open or read and WARNING: 1 listed file could not be read. A grep on the file name is enough for a visual check, but only --ignore-missing gives a usable exit code.


Choose the right algorithm

The four commands of the family work the same way: only the algorithm changes, and with it the resistance to attacks. An algorithm is "broken" when you know how to build two different files with the same checksum, a collision.

AlgorithmCommandLengthRecommended use
MD5md5sum128 bitsAvoid, collisions shown since 2004
SHA-1sha1sum160 bitsDeprecated, practical collision shown in 2017 (SHAttered)
SHA-256sha256sum256 bitsCurrent standard, use by default
SHA-512sha512sum512 bitsVery critical files, large backup archives

sha256sum is the right choice in every common Linux administration context. md5sum is only useful to detect an accidental corruption in an internal context with no security stake, for example comparing two copies of a file on a trusted local network: a disk failure does not build a deliberate collision.


Compare two files by their hash

The hash only depends on the content: two files with the same SHA-256 checksum are identical bit for bit, even if their name, date or location differ. It is the safest way to check that a copy is faithful, more reliable than comparing size or date.

Terminal window
cp archive.txt copie.txt
sha256sum archive.txt copie.txt
5522a2b250443947ae82340763670f86b15b97b120eadade6754a030b46cc0bd archive.txt
5522a2b250443947ae82340763670f86b15b97b120eadade6754a030b46cc0bd copie.txt

Consistency check script

In a script, you compare the two checksums rather than reading them by eye. cut -d' ' -f1 isolates the hash of each line, and the script exits with code 1 on a difference, which a monitoring tool or a scheduled task can use.

#!/bin/bash
SRC=$(sha256sum "$1" | cut -d' ' -f1)
DST=$(sha256sum "$2" | cut -d' ' -f1)
if [ "$SRC" = "$DST" ]; then
echo "Identical files: $1"
else
echo "DIFFERENCE DETECTED: $1 ≠ $2" >&2
exit 1
fi

gpg: verify a signature

A GPG signature is produced with the author's private key, and verified with their public key. A valid signature therefore proves that the file was signed by the holder of that key, whom you chose to trust. It is the check expected for distribution images, packages and tools whose authenticity is critical. gpg is not always installed on a minimal image: apt install gnupg or dnf install gnupg2.

Complete workflow

The workflow chains four steps. The outputs of step 4 were measured with a test key named "Auteur", created for the occasion: only the key identifier and the date will differ on your machine.

  1. Download the file, its checksum and its signature

    Terminal window
    wget https://example.com/tool-1.0.tar.gz
    wget https://example.com/tool-1.0.tar.gz.sha256
    wget https://example.com/tool-1.0.tar.gz.sig

    The signature can be in binary format (.sig) or ASCII armored (.asc).

  2. Import the author's public GPG key

    Terminal window
    # From a key server, by the fingerprint published by the project
    gpg --keyserver hkp://keyserver.ubuntu.com --recv-keys <FINGERPRINT>
    # From a URL provided by the project
    curl -fsSL https://example.com/release-signing-key.asc | gpg --import

    The key's fingerprint is published on the project's download page. Prefer it to the short 8-character identifier, far too easy to imitate.

  3. Check integrity with sha256sum

    Terminal window
    sha256sum -c tool-1.0.tar.gz.sha256
  4. Check authenticity with gpg

    Terminal window
    gpg --verify tool-1.0.tar.gz.sig tool-1.0.tar.gz
    gpg: Signature made Tue Sep 29 17:59:28 2026 UTC
    gpg: using EDDSA key A1BAA40648E731F8C99946613BB2AC3D535A7428
    gpg: Good signature from "Auteur <auteur@example.com>" [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: A1BA A406 48E7 31F8 C999 4661 3BB2 AC3D 535A 7428

    "Good signature" confirms that the file matches the signature, and gpg exits with code 0. The WARNING is normal if you just imported the key without certifying it yourself: it is GPG's trust model (Web of Trust). Compare the Primary key fingerprint line with the fingerprint published by the project, on several channels.

The two other verdicts are worth knowing. Without the public key, gpg answers Can't check signature: No public key and exits with code 2. On a file modified after signing, it answers BAD signature from "Auteur <auteur@example.com>" with code 1: the file must not be used.


Common practical cases

The three tabs follow the same pattern on real cases: a signed distribution image, a binary published with its checksum, and an internal backup whose checksum you produce yourself. The first one was replayed in full on 29 September 2026.

Terminal window
# Ubuntu 24.04: the directory holds the point releases (24.04.3 to 24.04.5)
wget https://releases.ubuntu.com/24.04/SHA256SUMS
wget https://releases.ubuntu.com/24.04/SHA256SUMS.gpg
wget https://releases.ubuntu.com/24.04/ubuntu-24.04.5-live-server-amd64.iso
# Import the key that signs the Ubuntu images
gpg --keyserver hkp://keyserver.ubuntu.com \
--recv-keys 843938DF228D22F7B3742BC0D94AA3F0EFE21092
# Verify the signature of the SHA256SUMS file
gpg --verify SHA256SUMS.gpg SHA256SUMS
# Check the downloaded ISO, without failing on the others
sha256sum -c --ignore-missing SHA256SUMS

The signature covers SHA256SUMS, not the ISO: you authenticate the list of checksums, then you check the ISO against it. gpg answers Good signature from "Ubuntu CD Image Automatic Signing Key (2012) <cdimage@ubuntu.com>".


Common troubleshooting

The messages of sha256sum and gpg are precise, provided you know how to read them. The table links each measured message to its cause and fix. One rule dominates: a FAILED or a BAD signature is never worked around, you download again from the official source.

SymptomCauseSolution
FAILED open or readListed file missing, or different nameCheck the name, or add --ignore-missing on a multi-entry SHA256SUMS
no properly formatted checksum lines foundThe file only holds the hashRebuild the line: echo "$(cat f.sha256) file" | sha256sum -c
computed checksum did NOT matchFile altered or truncatedDo not use it, download it again
Can't check signature: No public keyPublic key not importedgpg --recv-keys <FINGERPRINT> or import from the project's URL
BAD signatureFile altered or replacedDo not use it, download again from the official source
keyserver receive failed: No dataKey missing from this key serverUse the server or URL given by the project

Key points

  • sha256sum file generates the hash. sha256sum -c file.sha256 checks it.
  • --ignore-missing makes a multi-entry SHA256SUMS usable in a script.
  • sha256sum is the current standard. md5sum only detects accidental corruption, never a deliberate alteration.
  • A GPG signature proves authenticity; a checksum alone only checks integrity.
  • "Good signature" is positive, the trust WARNING is normal for a newly imported key: compare the fingerprint.
  • Store the .sha256 or .asc files separately from the archives to detect storage corruption.

Knowledge check

Check that the essentials of this guide stuck. The questions cover only what has just been explained here.

Knowledge check

Check what you have learned with this interactive quiz

6 questions
6 min
70% to pass

How it works

  • The timer starts when you click Start
  • Multiple choice, true/false and short answer questions
  • You can move between questions
  • Detailed results are shown at the end

Starts the quiz and the timer

Is this project useful to you?

The guides, courses, quizzes and labs stay free. If you use them regularly, you can contribute to their upkeep and development.

Become a supporting member (new tab) One-time support (new tab) Learn more

Follow the project on LinkedIn