How are signing key hashes a secure way to verify software?

There are many different hash algorithms in the wild with different use cases. There are primitive cryptographic hash algorithms (think SHA-2, SHA-256), there are extensions of that there are that take a private key to ascertain authentication (HMAC: Hash-based Message Authentication Code, like HMAC-SHA256) which are extensions of general MACs, and there are some non-cryptographic hashes to help validate data integrity (like CRC32).

Technically, yes, you could do an unsigned hash and hand it out. You see cases like this using checksums to validate what you’ve downloaded matches with what website you downloaded it from. i.e., Linux ISOs often provide checksums, like in secureblue.

Unsigned hashes can validate data integrity, but it does not authenticate. In the above example, you validate the checksum from the website matches the download, and that shows it hasn’t been tampered with in transit, or if you got the ISO from somewhere else that the checksums match. However, this does not indicate that secureblue themselves actually built the ISO, it just validates the binary hasn’t changed.

What happens if secureblue is hacked and a malicious user puts up a new malicious binary? How would you know that the binary you download isn’t from some evil third party user?

Well, something you can do is used a MAC (like HMAC). The owner of the code has a private key, and they could share that private key with everyone they trust, and then they post hashes of the software based on that key. The trusted users can download it, and validate the HMAC with the private key. This is a huge footgun: they gotta share their private keys to lots of people, and they have to pray they don’t go forging new software in their name!

So if we need to authenticate and not hand out private keys, we need to find a way to allow other users to validate what it published while keeping the private key secret. This leads us into public key cryptography (asymmetric cryptography). But we aren’t actually trying to encrypt our software (else no one could easily use it!) but we want to simply provide a “signature” alongside of it, specifically a digital signature.

Found the below image from here - you can see the flow does not require the verifier know the private key - they simply can use the verification algorithm with the public key. Here, a malicious user can’t forge a signature unless they know the private key, which we assume is safe.

With this, this basic digital signature algorithm is generally what can be used to validate software. But now we got a big problem: how do we share this public key from the signer?

  1. Simplest way is to simply walk up in person an ask. This is annoying, and not scalable.
  2. You can do Trust-On-First-Use (TOFU). i.e., you just assume the public key you get from a server. For example, the secrueblue website provides a GPP keyring with public keys which you can use to validate. This has issues as well, but not the worst.
  3. Certificate Authorities (CA). This is the current most common way to share public keys from a trusted source. For things like HTTPS, there are plenty of free CAs (think Let’s Encrypt), to help ensure the world has HTTPS enabled.

Back to software, typically you’d say signing software is called “code signing”. This is quite common. Look at some Window documentation, and there are free + paid options for specific CAs - MacOS has its own style as well. You can see any1 actually was handling that here for MacOS. And as I said before, secureblue uses TOFU-style sharing via their website to give you the public keys to validate (unless theirs is on a CA I’m not aware of).

Back to the secureblue example

  • Assume securblue is secure, and you download the keyring and download the ISO
  • You know how to verify secureblue
  • say Secureblue website gets hacked, user puts up a new binary and new keyring
    • You find the keyrings don’t match! You don’t trust the software.
  • Say secureblue website gets hacked, users buts up a new binary keeping the keyring the same
    • The GPG verification will fail