1

I'm trying to check the integrity of a set of downloaded files using sha256sum.

I cryptographically signed a digest file (named SHA256SUMS) with PGP. I create the file by recursively calculating the checksums of all the files in & under the current directory with

find . -type f -not -name SHA256SUMS -exec sha256sum '{}' \; >> SHA256SUMS

I can now verify the integrity of the files by (after checking the signature of the digest file, which is omitted from this question for simplicity) executing:

sha256sum -c SHA256SUMS

The above command will exit non-zero if any of the files in the digest file have a different contents from what's stored in the digest file.

However, it will not exit non-zero if there's some new file that's not listed in the digest.

I couldn't find any options in sha256sum to fail if there's an unexpected file.

How can I verify the integrity of a directory recursively using sha256sum, including failing on unverified files?

2
  • 1
    "I couldn't find any options in sha256sum to fail if there's an unexpected file" – This is because sha256sum -c SHA256SUMS does not traverse any directory tree, it reads pathnames from the given file. Any pathname not in the file is not its concern. You cannot find an unexpected file by just reading all expected pathnames from SHA256SUMS like sha256sum -c does; for this you need to actually traverse the directory tree like find does. Commented Mar 22, 2024 at 5:27
  • The functionality from the question can't be achieved using only sha256sum. You could parse the SHA256SUMS file and compare the list of files from that file to the output of find (1). Commented Mar 22, 2024 at 6:16

1 Answer 1

1

You can create a sorted list of files:

find . -type f | sort

As well as a sorted list of files with checksums:

find . -type f -print0 | sort -z | xargs -0 sha256sum

Then simply use cmp, diff -u or similar to compare the generated lists. If no files are added or removed, the results should be the same every time.


Instead of storing the file list separately, you can extract just the filenames from SHA256SUMS, for example using cut --bytes=67-.

Comparing just the file list (without checksums) would allow you to determine quickly whether files were added or removed, without calculating checksums for those files.

So all in all assuming your SHA256SUMS file is already present:

diff -u \
    <(cut --bytes=67- < SHA256SUMS) \
    <(find . -type f -not -name SHA256SUMS -print | sort)

If this shows no output, the file list is identical (possibly except for additional SHA256SUMS files in subdirectories, since find excludes those as well).


Yet another corner case is if sha256sum encounters files with no read permission. It would not be printed to stdout at all, so you either have to check that no errors occured when generating the list, or also capture the stderr output.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.