Software is valuable and becoming more so. The more valuable it becomes, the more it is a target for attack, and as Sun Tzu famously wrote, "All warfare is based on deception."

Because we’re depending more on our software to provide vital functions for our lives, including using Bitcoin to store our money, it's more important than ever that we counter deception in software by verifying its authenticity. Otherwise, we may be victims of bad software such as the Bitcoin-stealing trojan detected in downloadable versions of popular Mac applications such as BBEdit, Pixelmator, Angry Birds, and Delicious Library.

The process of authentication requires technical proficiency and takes a bit of effort but it’s worth the peace of mind.


  • This article assumes the use of macOS but the technique can be performed on Linux and Windows as well.
  • You should have proficiency using the command line.
  • I recommend you purchase an HSM such as the YubiKey.


How do we determine authenticity? In the old days it was done with seals and impressions:

Today it can be done digitally and the terminology has changed slightly:


I certify authenticity of the document by affixing an impression created by my seal.


I certify authenticity of the file by signing it with my key.

We can observe a signature created by the software maker with her key, but that raises a new question: How do we know the key is actually hers? In the digital world we can use the authentication process again: The software maker’s key can be certified as authentic by someone else. If you trust the other person, you know the software maker’s key is authentic, that her signature on the software is authentic, and in turn that the software is authentic. Altogether, it looks like this:

Chain of Trust

your signature → your friend’s key → your friend’s signature → stranger’s key → …* → stranger’s signature → software maker’s key → signature → software

*There may be a number of strangers between you and the software maker in the chain of trust.

When many people sign each other’s keys to facilitate this process, they create multiple interweaving chains of trust. We call these chains the Web of Trust. To know that software you care about is authentic you need to join the Web of Trust.

This document is a series of step-by-step instructions for how to verify that software is authentic using Bitcoin-Qt as an example.


  1. Download and install GnuPG if you haven’t already.
  2. For increased security I recommend you generate your keys on an HSM such as the YubiKey. If you just bought a YubiKey, first configure it to require button-press authorization for cryptographic operations.
  3. Create your own key pair if you don’t already have one.
    1. Be sure to generate the keys directly on the HSM (instructions for YubiKey).
    2. Use a keysize of 4096 bits as the Debian developers do.

Example: Bitcoin-Qt

  1. Go to the download page.
  2. Download the file bitcoin-0.8.5-macosx.dmg.
  3. Click Verify release signatures on the download page to find signed hashes of the program.
  4. Download the hashes (the file SHA256SUMS.asc, download using this link).
  5. Open Terminal.
  6. Check that the hash matches the file:
    $ shasum --check SHA256SUMS.asc
    shasum: bitcoin-0.8.5-linux.tar.gz: No such file or directory
    bitcoin-0.8.5-linux.tar.gz: FAILED open or read
    bitcoin-0.8.5-macosx.dmg: OK
    shasum: bitcoin-0.8.5-win32-setup.exe: No such file or directory
    bitcoin-0.8.5-win32-setup.exe: FAILED open or read
    shasum: No such file or directory FAILED open or read
    shasum: WARNING: 3 of 4 listed files could not be read
  1. Notice that the line containing the file you downloaded ends in OK.
  2. Verify the signature on the hashes:
    $ gpg --verify SHA256SUMS.asc
    gpg: Signature made Thu Sep 12 21:27:02 2013 ART using RSA key ID 1FC730C1
    gpg: requesting key 1FC730C1 from hkp server
    gpg: key 1FC730C1: public key "Gavin Andresen (CODE SIGNING KEY)" imported
    gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
    gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u
    gpg: next trustdb check due at 2015-08-18
    gpg: Total number processed: 1
    gpg: imported: 1 (RSA: 1)
    gpg: Good signature from "Gavin Andresen (CODE SIGNING KEY)"
    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: 2664 6D99 CBAE C9B8 1982 EF60 29D9 EE6B 1FC7 30C1
  1. Notice that there is no indication that the signature belongs to the owner. This tells you that you need to join the Web of Trust in order to know that the program is authentic.

How to Join the Web of Trust

Start by joining Keybase. It's an excellent free service that's promoting the web of trust.

  1. Authenticate someone you know by signing their key. Before signing someone’s key, you should do the following while having a conversation with them. Ideally this conversation should happen in person, but having it over video conferencing is OK. Do not have the conversation over SMS, email, nor the telephone.
    1. Download the key.
      1. Ask your friend for their Key ID. They can see it in GPG Keychain by double clicking on their key. It’s OK for them to send you their ID via email or other means.
      2. Download the key with the menu item Key/Lookup key on key server….
    2. Verify the identify of the key owner.
      1. Double click on the downloaded key and look at the fingerprint.
      2. Ask the key owner to read to you the fingerprint from their screen and confirm that it matches exactly the one on yours.
    3. Prove that the owner is in control of their key*.
      1. Create a random file for the owner to sign:

        $ gpg --gen-random 0 1000 > nonce
    1. Send the `nonce` file to them and ask them to sign it.  They can sign the file with this command: <blockquote class="terminal">

$ gpg --detach-sign nonce

    1. You will see the message `You need a passphrase to unlock the secret key`.  If you have entered your passphrase recently then you won’t actually be asked for your passphrase again.
    1. Ask them to send the signature (`nonce.sig`) to you.  Place it in the same folder as your `nonce` file.
    1. Verify the signature: <blockquote class="terminal">

$ gpg --verify nonce.sig nonce
gpg: Signature made Thu Sep 12 21:27:02 2013 ART
gpg: using RSA key 0x29D9EE6B1FC730C1
gpg: Good signature from "Gavin Andresen (CODE SIGNING KEY)" [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: 2664 6D99 CBAE C9B8 1982 EF60 29D9 EE6B 1FC7 30C1

    1. Look for a `good signature` and make sure the `Primary key fingerprint` matches the fingerprint of the key from step 1.2.
  1. Sign the key using Key/Sign….
  2. Send the key, along with your new signature, to the keyserver with Key/Send public key to key server.
  3. Have your friend authenticate you by repeating the process with your key.
    1. Delete the files nonce and nonce.sig before starting the process again so they don’t get mixed up with the new versions.
  4. Congratulations, you’re now in the Web of Trust. Repeat this process with as many people as you can to increase your integration into the web and to increase your confidence in the authenticity of the keys.