When you distribute software—especially binaries—you’re making an implicit promise: this file is exactly what I intended to ship. Checksums are how you keep that promise.
In this article we’ll go through what checksums are, why they matter, and how to add them to your own open source project. Let’s get started!
What is a checksum?
A checksum is a fixed-length value derived from a file’s contents using a cryptographic hash function. SHA256 is the gold standard, so unless you have a specific reason to use another algorithm, best to stick with SHA256. If even a single byte of the file changes, the checksum changes completely. After downloading the file, the checksum can be computed and compared against the advertised value. Thus, a checksum is basically a way of saying “yes, this program is what it claims to be.”
To summarize…
Checksums (in this context) can…
- Detect corruption after downloading a file
- Detect tampering after downloading a file
- Provide confidence to end users
Checksums cannot…
- Prove who created the file
- Protect against malicious servers publishing a tampered with file and corresponding checksum
A note on package managers
You may be wondering if you’re currently as risk for any attacks or malware because of the 20,000 npm packages you installed within the past couple minutes. However, nearly all package managers have some sort of safety net that verifies the integrity of the download before installing. Binaries that are not distributed by a package manager (via GitHub releases and the like) don’t have that built in. Just something to keep in mind.
Adding checksums to your project
Adding checksums to your open source project is actually quite simple. Just make sure you put them in the right place or they won’t work.
Build artifacts
↓
Package artifacts (tar.gz, zip, binaries)
↓
Generate checksums
↓
Publish artifacts + checksums
↓
Create release
My current project, Doclific, uses a single file (checksums.txt) containing the checksums followed by two spaces, then the specific file.
a21bd2e10abbdb057e8acd91a331b5ff6e187e845031f22d0117927e276d6b4f doclific-v0.1.1-darwin-amd64.tar.gz
a8c91ead81f402e380293f9a0fa6cf56cf380782dbfdff9bc604548bf14a35da doclific-v0.1.1-darwin-arm64.tar.gz
499224f4d05f023c560978c6fff2bbb381b7425e742e0b5b3c4b54068d7f6dfb doclific-v0.1.1-linux-amd64.tar.gz
1913c0669ec383133e8460a0be9df43e285a5ebc39928e62c86fcb6c9b486665 doclific-v0.1.1-linux-arm64.tar.gz
I generate the file in my release.sh file which runs every time I create a new release.
echo "🔐 Generating checksums"
cd "$DIST_DIR"
shasum -a 256 * > checksums.txt
Then when the user runs the command curl -fsSL https://raw.githubusercontent.com/muellerluke/doclific/main/scripts/install.sh | bash it will pull the install.sh script and run it. Inside the install script, it generates a checksum based upon the downloaded file and checks to make sure it matches that of the hosted checksum.txt file in the release.
info "Verifying checksum..."
# Determine command
if command -v sha256sum >/dev/null 2>&1; then
CHECKSUM_CMD="sha256sum -c -"
elif command -v shasum >/dev/null 2>&1; then
CHECKSUM_CMD="shasum -a 256 -c -"
else
err "No SHA256 checksum tool found. Please install sha256sum or shasum."
fi
# Run checksum verification
grep "$ARCHIVE" "$CHECKSUM_FILE" | $CHECKSUM_CMD || err "Checksum verification failed"
Note: some OS version may or may not have shasum installed, so I first check to see if it is or use sha256 if it is not.
Closing thoughts
Again, if you're distributing software via a package manager, you generally don't have to worry about this. However, if you're distributing a binary outside of a package manager using curl or something else, then implementing checksums will provide an added layer of security and confidence for your end users.
Top comments (0)