Taco Steemers

A personal blog.

Checking checksums

Topic

This page is about file hashes (checksums) for situations where the distributor of the file also provides the checksum.

If you want to use checksums in your own code you might want to look at the CRC-32 algorithm .

The examples here are for SHA 256 checksums but can easily be adjusted to SHA 512, for example. OpenSSL is also easy to use for any algorithms.

SHA checksums

If available, we always want to compare a given checksum with the checksum of the file we downloaded. This is to make sure nothing went wrong during transit, in memory or in storage. Another reason is to make it less likely we fall for a man-in-the-middle attack. Checking the checksum for that reason will only work if the man in the middle is not in a position to manipulate the page that lists the checksum.

First, create or check your checksum file

Before we run a checksum command on a file we need to have a corresponding checksum file from the distributor of the file. For example, I download a gradle binary distribution and the corresponding checksum file:

https://services.gradle.org/distributions/gradle-6.9.1-bin.zip
https://services.gradle.org/distributions/gradle-6.9.1-bin.zip.sha256

The contents of this checksum file is only the has, as we see here:

$ cat gradle-6.9.1-bin.zip.sha256
8c12154228a502b784f451179846e518733cf856efc7d45b2e6691012977b2fe

The checksum tools that I use on Linux and macOS expect a format like the following:

8c12154228a502b784f451179846e518733cf856efc7d45b2e6691012977b2fe  gradle-6.9.1-bin.zip

Note that there are two spaces used here. Apparently the missing character in between the spaces means the file will be interpreted as regular text, which is what we want.

Let's create that file now, so we can use it in our examples:

$ echo "$(cat gradle-6.9.1-bin.zip.sha256)  gradle-6.9.1-bin.zip" > gradle-6.9.1-bin.zip.sha256.checksum

Using sha256sum (GNU)

sha256sum is available on GNU/Linux distributions, as part of the coreutils. As far as I know, sha256sum is not available on brew or macports.

$ cat gradle-6.9.1-bin.zip.sha256.checksum | sha256sum --check
gradle-6.9.1-bin.zip: OK

With --status it only gives a 0 status code for success and 1 otherwise. Useful for when you want to check the status code in scripts.

$ cat gradle-6.9.1-bin.zip.sha256.checksum | sha256sum --check --status

We can also use it to create a checksum:

$ sha256sum gradle-6.9.1-bin.zip
8c12154228a502b784f451179846e518733cf856efc7d45b2e6691012977b2fe  gradle-6.9.1-bin.zip

Using shasum (more cross-platform)

shasum is available to Linux distributions and macOS. On macOS it needs to be installed with brew or macports.

We need to indicate which algorithm to use, with the -a argument.

$ cat gradle-6.9.1-bin.zip | shasum -a 256 -c gradle-6.9.1-bin.zip.sha256.checksum
gradle-6.9.1-bin.zip: OK

Returning a statuscode works the same as it does with sha256sum:

$ cat gradle-6.9.1-bin.zip | shasum -a 256 -c gradle-6.9.1-bin.zip.sha256.checksum --status

As does creating a checksum:

$ shasum -a 256 gradle-6.9.1-bin.zip
8c12154228a502b784f451179846e518733cf856efc7d45b2e6691012977b2fe  gradle-6.9.1-bin.zip

Using OpenSSL

openssl can also generate the hash for us.

$ openssl sha256 gradle-6.9.1-bin.zip
SHA256(gradle-6.9.1-bin.zip)= 8c12154228a502b784f451179846e518733cf856efc7d45b2e6691012977b2fe

Comparing hashes by hand

With sha356sum and shasum we can let the tool compare the hashes. Maybe we are using a tool that doesn't do the comparison for us, like openssl. In that case comparing hashes can be easy with python or any other scripting language. We start the console, and copy and paste the hashes to do a string comparison.

$ python
>>> "the hash" == "the hash"
True
>>> quit()

We do need to make sure we did copy and paste the two different hashes, instead of pasting the one hash twice. One way to be sure is copying and pasting something else before we copy and paste the second hash.