Verify Your Bitcoin Core Download

Justin Moon

Posted on December 26, 2020

When you visit bitcoincore.org to download the Bitcoin software, you're greeted with a page like this.

If you're like me, you smash the blue "Download" button, say a prayer to the Virgin Mary, and hope your bitcoins don't disappear!

But there's a better way. That "Verify release signature" link is front-and-center for a reason. It helps you prove to yourself that you downloaded the real Bitcoin software. Let's go over how this works so you can more confidently use Bitcoin in the future.

SHA256SUMS.asc

When you click that "Verify release signature" link it will download a SHA256SUMS.asc file like the one below. (Note: In future this exact file will remain available here. You can also try this tutorial with future releases of Bitcoin Core, but the hashes and filenames will be different.).

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

60c93e3462c303eb080be7cf623f1a7684b37fd47a018ad3848bc23e13c84e1c  bitcoin-0.20.1-aarch64-linux-gnu.tar.gz
55b577e0fb306fb429d4be6c9316607753e8543e5946b542d75d876a2f08654c  bitcoin-0.20.1-arm-linux-gnueabihf.tar.gz
b9024dde373ea7dad707363e07ec7e265383204127539ae0c234bff3a61da0d1  bitcoin-0.20.1-osx64.tar.gz
c378d4e21109f09e8829f3591e015c66632dff2925a60b64d259be05a334c30b  bitcoin-0.20.1-osx.dmg
fa71cb52ee5e0459cbf5248cdec72df27995840c796f58b304607a1ed4c165af  bitcoin-0.20.1-riscv64-linux-gnu.tar.gz
4bbd62fd6acfa5e9864ebf37a24a04bc2dcfe3e3222f056056288d854c53b978  bitcoin-0.20.1.tar.gz
930b96e774f5fe4795b9a3c0d4fd1da278d2b0777c9401dea3ba7453f8bbe14c  bitcoin-0.20.1-win64-setup.exe
e59fba67afce011d32b5d723a3a0be12da1b8a34f5d7966e504520c48d64716d  bitcoin-0.20.1-win64.zip
376194f06596ecfa40331167c39bc70c355f960280bd2a645fdbf18f66527397  bitcoin-0.20.1-x86_64-linux-gnu.tar.gz
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)gg

iQIcBAEBCAAGBQJfJU5lAAoJEJDIAZ42wulkAbAP/1pyFrxMrUFlNJdA8yCr0Dj5
5FBBGzFhVrAU+ouiJrPOf/X1HSM8haZ2TSsdI7Mg+S9wbMfFPBmeTIZNtdPkrEfB
YWEWqkhYZZoSGxaOwQVyQmBTLyvlZcLM0Tuz5cVTcJ4ttFnrZBAcr251MVYRbJWx
RxVb67GBgO7OOmxTfRIrgKLHAZo7zTdpPrSMhHEfcarf0A1r4xwUJCtNFRtBUQXi
uacUessZCeZ3x+qoqRHdoeVJDXzshFzqVx7jLMMTKUgQ7HBiH+sWOwZi8VFeCI8u
XgzPW6lv5Y1F5gOjfbHq+N+PggOBBukIKTHx9m6y60RSRXB08DwDnAldK900L+LD
8QUBNxzbCIKx65W80Nhb1GZxIWm89byvb1BR8LCk/P+8MBppp8x9zWfAdtOmnFXG
pl34Q0en8dZvd+0tpNmEKcNHNVzVCF1hFmf9PPS6DW/AzFzYjVggsB1LKLbThjts
XtdB5wcCEbFWSFsH3th/j7+gA1UkE6gnxq2lZdNQMV99KDZf6oP+XykKeq7xFIWG
y2omYiRiFw9UkiUDNIhrE2wHA+VDCsOUwo2HM0dGJ/ZegdqLO5YjNP0nOi3Q9JP5
TeQF/DvkVTnU/ex0URkbkYY6SDod0f1KasFm1Ft3ygL9FXDncgYycYvAn7T7M3Wv
QSEtaREvgcH90iLyHl90
=szhI
-----END PGP SIGNATURE-----

This is a PGP-signed message. There are two parts:

  • The text between -----BEGIN PGP SIGNED MESSAGE----- and -----BEGIN PGP SIGNATURE----- is the message.
  • The text between -----BEGIN PGP SIGNATURE----- and -----END PGP SIGNATURE----- is a PGP signature of that message.

The message declares the correct SHA-256 hashes for different releases of the Bitcoin Core software. In order to use this file to verify our Bitcoin Core download, we must check 2 things: that we get the same value when we hash our download of the Bitcoin software, and that the PGP signature is valid. Let's start with the PGP signature.

Verify PGP Signature

Let's verify the signature inside SHA256SUM.asc:

$ gpg --verify SHA256SUMS.asc 
gpg: Signature made Sat 01 Aug 2020 06:13:41 AM CDT
gpg:                using RSA key 90C8019E36C2E964
gpg: Can't check signature: No public key

Interesting. PGP can't verify this signature because it doesn't have the public key. But it knows which PGP key it doesn't have: 90C8019E36C2E964. This is a PGP "key ID" which is one way PGP public keys are identified. One of these key ID's is embedded in the signature we're dealing with.

The downloads page on bitcoincore.org tells us which key is used for this signature and how to obtain it: 01EA5486DE18A882D4C2684590C8019E36C2E964. Notice anything about it?

It ends with 90C8019E36C2E964, our PGP key ID! Let's download the full public key using the fingerprint from bitcoincore.org:

$ gpg --keyserver hkp://keyserver.ubuntu.com --recv-keys 01EA5486DE18A882D4C2684590C8019E36C2E964
gpg: key 90C8019E36C2E964: public key "Wladimir J. van der Laan (Bitcoin Core binary release signing key) <laanwj@gmail.com>" imported
gpg: Total number processed: 1
gpg:               imported: 1

Looking good. We once again see our key id, and the description of the key "Wladimir J. van der Laan (Bitcoin Core binary release signing key) laanwj@gmail.com" sounds like what we're looking for.

Now that we have the public key, let's try to verify the signature again:

$ gpg --verify SHA256SUMS.asc 
gpg: Signature made Sat 01 Aug 2020 06:13:41 AM CDT
gpg:                using RSA key 90C8019E36C2E964
gpg: Good signature from "Wladimir J. van der Laan (Bitcoin Core binary release signing key) <laanwj@gmail.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: 01EA 5486 DE18 A882 D4C2  6845 90C8 019E 36C2 E964

A few notes:

  • "Good signature" means the signature was cryptographically valid
  • "WARNING: This key is not certified with a trusted signature!" means that PGP doesn't place a high degree of trust in the public key we just downloaded from the internet. If you really wanted to trust this key, it would be ideal to meet Wladimir at a bitcoin conference and ask for it in person. Or maybe ask a few friends for it and make sure everyone gives you the same key. PGP has commands to mark such public keys with greater trust. We can ignore this message for now.

Verify File Hash

Now that we're reasonably convinced the Bitcoin Core release signing key signed that list of hashes, let's download a release of the Bitcoin software, hash it, and see if we get a match.

The first line in the PGP message asserts that when you SHA-256 hash bitcoin-0.20.1-aarch64-linux-gnu.tar.gz you will get 60c93e3462c303eb080be7cf623f1a7684b37fd47a018ad3848bc23e13c84e1c. Let's verify this. You can download the file here. These instructions should work on Linux and MacOS:

# download the file
$ curl -O https://bitcoincore.org/bin/bitcoin-core-0.20.1/bitcoin-0.20.1-aarch64-linux-gnu.tar.gz

# the file is present
$ ls 
bitcoin-0.20.1-aarch64-linux-gnu.tar.gz

# hash the file, and the hash looks similar
# on MacOS use `shasum -a 256` instead of `sha256sum`
$ sha256sum bitcoin-0.20.1-aarch64-linux-gnu.tar.gz
60c93e3462c303eb080be7cf623f1a7684b37fd47a018ad3848bc23e13c84e1c  bitcoin-0.20.1-aarch64-linux-gnu.tar.gz

# better than visual inspections, sha256sum has a --check flag that 
# will look for every file in the list, hash it and compare.
# --ignore-missing only checks files that are present in current directory 
$ sha256sum --ignore-missing --check SHA256SUMS.asc
bitcoin-0.20.1-aarch64-linux-gnu.tar.gz: OK
sha256sum: WARNING: 20 lines are improperly formatted

We're now convinced that Wladimir signed the PGP message and that the copy of the Bitcoin software we downloaded is exactly the same as the one he released -- because they hash to the same value. You should be able to use this and future releases with greater confidence.

But one question remains. Why does Wladimir get to choose the hashes? Are we placing an unreasonable amount of trust in one person? In the next post I'll explain how Bitcoin Core developers use a system called Gitian to enable anyone to independently build these releases and arrive at consensus on the correct hashes before the software is ever released. Wladimir's signature reflects this consensus, not his personal opinion.

Mooniversity Newsletter

Receive emails about new articles and courses