The Curious Case of Digital Signatures

Good questions demand good answers

Playing around PGP last night ( yes, late into the game - it takes time to sort things out one by one. ) so here is my understanding of the logic of verifying software:
  1. you import the specific APP's public key from the terminal
  2. download both the software and the signature file (asc)
  3. copy and paste a line of code into the terminal to verify
But how does it work in the background - is it verifying the signature file matches with the public key? and how things be if someone changed the app, the signature then unmatched with the public key? 🤔
I like such questions since they motivate me to dig deeper. I actually didn't really know anymore how it works in detail so I wasn't able to answer these questions with confidence but I would have loved to. I mean, I am the founder of ~crypto! What kind of LARPer would I be if I can't even explain how gpg --verify works?
So I decided to be less of a LARPer and do some research. In this post, I present you the result of my research and my attempt to explain this in an easy to understand way.1
I'll use Sparrow Wallet and a person that is learning from first principles how signatures are verified with and by gpg --verify (basically me after getting nerd sniped by @Natalia's questions) as an example.

Purpose of Digital Signatures

Digital signatures are commonly used to ensure the integrity and authenticity of software. When you verify a digital signature, you make sure that the software was created by the person you trust and think it was created by (authenticity) and that it was not modified (integrity).
You usually download the signature from the same location as the software. For example, this location is https://sparrowwallet.com/download for Sparrow Wallet:
The signature is the file sparrow-1.8.2-manifest.txt.asc. It contains the following content:
-----BEGIN PGP SIGNATURE----- Comment: GPGTools - http://gpgtools.org iQIzBAABCgAdFiEE1NDTIC/AaEmiV7ON6UYYM0xnS0AFAmWo/vYACgkQ6UYYM0xn S0B40RAAteFi0MBNKY80txOOFmcChAAgcLSnaH3Hd8AaKjijFdvYGvUAebP1EMBj 58K2p14aHq6rdEn2it8aQV4pO9sk9l9q6Fp0YObkJoWkcLL4r1fy4RVxgYFTo7D4 UkpigS4ulxrot5ChSzVxD5HTOsCFk1xrrWr77vWE2PiZ4w+L8d1+6rRdzPp6Yftl 7rF3Hb5x4aiZVKBqoSYbmBiPybLnCdXP0gxSYd4JZeyQ44XSOirNEO07w+tdwYPP 1fR09nBdcnF/BD1SPjCKL3P0YqWE04vJ+7XesdesMReAcxAntjlfRmGAlbbX0v60 MzNoM6vN/H9rfY6WXCJ5JJpdufulm11GbYAbC8rbSBNTXwxVY6czhMmG2cuQ7Euy AJ+1sPzh5U+hWAELOxI80atkQ8KSmw0kBnEP2H4bNMB4C48gU3tX2rEmvIZTHTN7 QLUr08y5FscWftlwJ1uqkGVr32JKZNnoLgL0VVlwlPquHNeX5OjNn6nWc3w2AQ7q j8tDZlzLnvFhvvRL4l1EO65PEg0zoL0LJVRSuoEs85o6ZKSJ0rUH9+jO1+4kUnzx ypR4KM40swCrP4DpuNLuc4p4Os0XFDdRKxcx2q3PH06+N1soAh5NJiXZRsOlEl9q NitWcDrzqKdZfYTevuTzbDMk/EikdRzfIe4KgcsutEiaKk7opQc= =m0CZ -----END PGP SIGNATURE-----
Let's assume you don't trust this location for some reason. You might be a new user and thus don't know if this is the official, legit website to download Sparrow. Or you simply don't want to rely solely on SSL/TLS certificates.
However, you want to learn how to verify digital signatures as mentioned. You want to be a smart cookie!

The Insanity of Web of Trust

You start with importing the public key as explained in the download page:
$ curl https://keybase.io/craigraw/pgp_keys.asc | gpg --import % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 5588 100 5588 0 0 14944 0 --:--:-- --:--:-- --:--:-- 15021 gpg: key E94618334C674B40: public key "Craig Raw <craig@sparrowwallet.com>" imported gpg: Total number processed: 1 gpg: imported: 1
One important detail is here that the public key is not provided via the same location. If the location is compromised, it could simply replace the public key with a public key controlled by an adversary which in turn compromises the whole scheme.
However, the instructions to download the public key are provided at the same location. So couldn't they also have been replaced?
Exactly right! However, we can go to https://keybase.io/craigraw and check if there is some useful information that makes the public key more trustworthy2:
We find some linked profiles and followers as sources of trust. We find proofs next to the linked profiles.
Here is the proof that the Github account craigraw controls this account on Keybase:
and here is a tweet proving the same for @craigraw:
Finally, we check that the key fingerprint matches the fingerprint shown in the proofs:
Checking the fingerprint of the key we received via gpg --list-keys --keyid-format long:
$ gpg --list-keys --keyid-format long craig@sparrowwallet.com pub rsa4096/E94618334C674B40 2019-10-03 [SC] [expires: 2027-09-18] D4D0D3202FC06849A257B38DE94618334C674B40 uid [ unknown] Craig Raw <craig@sparrowwallet.com> sub rsa4096/3FB2D3544ECAF6DA 2019-10-03 [E] [expires: 2027-09-18]
The fingerprint D4D0D3202FC06849A257B38DE94618334C674B40 matches. Great!
After you did your due diligence like a real believer in Web of Trust, you can use gpg --edit-key craig@sparrowwallet.com to specify how much you trust this key now:
$ gpg --edit-key craig@sparrowwallet.com gpg (GnuPG) 2.4.3; Copyright (C) 2023 g10 Code GmbH This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. pub rsa4096/E94618334C674B40 created: 2019-10-03 expires: 2027-09-18 usage: SC trust: unknown validity: unknown sub rsa4096/3FB2D3544ECAF6DA created: 2019-10-03 expires: 2027-09-18 usage: E [ unknown] (1). Craig Raw <craig@sparrowwallet.com> [ revoked] (2) Craig Raw <craigraw@gmail.com> gpg>
Enter the command trust to edit the key trust:
gpg> trust pub rsa4096/E94618334C674B40 created: 2019-10-03 expires: 2027-09-18 usage: SC trust: unknown validity: unknown sub rsa4096/3FB2D3544ECAF6DA created: 2019-10-03 expires: 2027-09-18 usage: E [ unknown] (1). Craig Raw <craig@sparrowwallet.com> [ revoked] (2) Craig Raw <craigraw@gmail.com> Please decide how far you trust this user to correctly verify other users' keys (by looking at passports, checking fingerprints from different sources, etc.) 1 = I don't know or won't say 2 = I do NOT trust 3 = I trust marginally 4 = I trust fully 5 = I trust ultimately m = back to the main menu Your decision?
The option 5 "I trust ultimately" should only be used with your own keys.

Sanity checks

After you have decided that you don't care about Web of Trust verified the received public key, you download the signature now. But you don't download the software just yet. You want to do a sanity check:
If there is no software to verify, running gpg --verify shouldn't make sense, right? But what would it do?
So like the curious person that you are and that assumes sanity is not a given but must be earned, you run gpg --verify <signature> in a folder which contains only the signature (sparrow-1.8.2-manifest.txt.asc) and expect the command to fail in some way. If you are on the right track, the error message should also not surprise you:
$ ls total 4.0K -rw-r--r-- 1 ekzyis ekzyis 873 Feb 23 15:42 sparrow-1.8.2-manifest.txt.asc $ gpg --verify sparrow-1.8.2-manifest.txt.asc gpg: no signed data gpg: can't hash datafile: No data
Looks like gpg indeed threw an error! Congratulations, you are not insane (yet) and maybe even on a good path to absolute wisdom (or at least being a smart cookie). Additionally, it seems like it even threw two errors: "no signed data" and "can't hash datafile: No data".
You are not sure what they mean though. So you start reading the documentation of gpg --verify since RTFM is always a good start to understand things better:
verify <signature> <document>
This command verifies a document against a signature to ensure that the document has not been altered since the signature was created. If <signature> is omitted, gpg will look in <document> for a clearsign signature.
Since we only gave a single argument to gpg --verify, gpg tried to find a clearsign signature in the provided file. But what is a clearsign signature? You start reading more documentation, this time for gpg --sign:
Clearsigned documents
A common use of digital signatures is to sign usenet postings or email messages. In such situations it is undesirable to compress the document while signing it. The option --clearsign causes the document to be wrapped in an ASCII-armored signature but otherwise does not modify the document.
alice% gpg --clearsign doc You need a passphrase to unlock the secret key for user: "Alice (Judge) <alice@cyb.org>" 1024-bit DSA key, ID BB7576AC, created 1999-06-04 -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 [...] -----BEGIN PGP SIGNATURE----- Version: GnuPG v0.9.7 (GNU/Linux) Comment: For info see http://www.gnupg.org iEYEARECAAYFAjdYCQoACgkQJ9S6ULt1dqz6IwCfQ7wP6i/i8HhbcOSKF4ELyQB1 oCoAoOuqpRqEzr4kOkQqHRLE/b8/Rw2k =y6kj -----END PGP SIGNATURE-----
Aha! You look at the signature that you have and see that it only seems to include a signature but not a document or message. There is no -----BEGIN PGP SIGNED MESSAGE-----:
-----BEGIN PGP SIGNATURE----- Comment: GPGTools - http://gpgtools.org iQIzBAABCgAdFiEE1NDTIC/AaEmiV7ON6UYYM0xnS0AFAmWo/vYACgkQ6UYYM0xn S0B40RAAteFi0MBNKY80txOOFmcChAAgcLSnaH3Hd8AaKjijFdvYGvUAebP1EMBj 58K2p14aHq6rdEn2it8aQV4pO9sk9l9q6Fp0YObkJoWkcLL4r1fy4RVxgYFTo7D4 UkpigS4ulxrot5ChSzVxD5HTOsCFk1xrrWr77vWE2PiZ4w+L8d1+6rRdzPp6Yftl 7rF3Hb5x4aiZVKBqoSYbmBiPybLnCdXP0gxSYd4JZeyQ44XSOirNEO07w+tdwYPP 1fR09nBdcnF/BD1SPjCKL3P0YqWE04vJ+7XesdesMReAcxAntjlfRmGAlbbX0v60 MzNoM6vN/H9rfY6WXCJ5JJpdufulm11GbYAbC8rbSBNTXwxVY6czhMmG2cuQ7Euy AJ+1sPzh5U+hWAELOxI80atkQ8KSmw0kBnEP2H4bNMB4C48gU3tX2rEmvIZTHTN7 QLUr08y5FscWftlwJ1uqkGVr32JKZNnoLgL0VVlwlPquHNeX5OjNn6nWc3w2AQ7q j8tDZlzLnvFhvvRL4l1EO65PEg0zoL0LJVRSuoEs85o6ZKSJ0rUH9+jO1+4kUnzx ypR4KM40swCrP4DpuNLuc4p4Os0XFDdRKxcx2q3PH06+N1soAh5NJiXZRsOlEl9q NitWcDrzqKdZfYTevuTzbDMk/EikdRzfIe4KgcsutEiaKk7opQc= =m0CZ -----END PGP SIGNATURE-----
You scroll a bit down in the documentation and see that it also mentions detached signatures:
Detached signatures
A signed document has limited usefulness. Other users must recover the original document from the signed version, and even with clearsigned documents, the signed document must be edited to recover the original. Therefore, there is a third method for signing a document that creates a detached signature. A detached signature is created using the --detach-sig option.
Well, that sounds interesting. You are now happy about your reading comprehension skills and are pretty sure that what you have is a detached signature. This explains both errors from before. There was no data included and gpg then tried to find the document that was signed in some way but couldn't find it. Poor gpg.
The online documentation however does not seem to explain where gpg tries to find the document. However, there is also the command man which stands for the M in RTFM. So you give man gpg a shot and search for --verify. You find this note among many other notes:
--verify:
[...] Note: If the option --batch is not used, gpg may assume that a single argument is a file with a detached signature, and it will try to find a matching data file by stripping certain suffixes. Using this historical feature to verify a detached signature is strongly discouraged; you should always specify the data file explicitly.
You ignore the "strongly discouraged" and want to do another sanity check:
If I understand correctly what I just read, gpg tried to remove "certain suffixes" to find the data file. I wonder what will happen if I download the software and put it in the same folder ...
So you do exactly that and run gpg --verify again:
$ ls total 106M -rw-r--r-- 1 ekzyis ekzyis 873 Feb 23 15:42 sparrow-1.8.2-manifest.txt.asc -rw-r--r-- 1 ekzyis ekzyis 106M Feb 23 20:17 sparrow-1.8.2-x86_64.tar.gz $ gpg --verify sparrow-1.8.2-manifest.txt.asc gpg: no signed data gpg: can't hash datafile: No data
Mhh, same error. So something is wrong. You double-check the file names and realize that when you strip .txt.asc, you get sparrow-1.8.2-manifest and not sparrow-1.8.2-x86_64.tar.gz! So gpg could still not find what you seem to call "software", the documentation seems to call "document" and the program itself seems to call "datafile" (consistency must be a virtue) simply by stripping suffixes. Everything makes enough sense again—for now.
You check the download page again and see that there is a file named sparrow-1.8.2-manifest.txt.
That looks very promising. It's the same file name as the signature just without .asc at the end. Now it should work.
You download it and look inside:
$ cat sparrow-1.8.2-manifest.txt 541b82e83ec928e7b54490211fa5e9d3b315394d895aebeab9a9696ce24c378d *Sparrow-1.8.2-aarch64.dmg 508a5ba212c2393a9d4cd122c2a8aa8b16e593c640bc3e4ac111ee574b2fd82d *Sparrow-1.8.2-x86_64.dmg 1035fc5663e53ce3a7d87a63a1dadc33bb180ceb3154549b251407b09db202b7 *Sparrow-1.8.2.exe 8ff8e70886af91c8758509097a1047a05341b29a2407934c49b6885ff71c60c2 *Sparrow-1.8.2.zip afee92405d3013d24add5e3099cea86f5201829b8f5f485f26b753af109619b9 *sparrow-1.8.2-1.aarch64.rpm 22b72b62865d8e9d0dcf71dc0907a3945f7a5c859257db4f05ee5b815c4bc56d *sparrow-1.8.2-1.x86_64.rpm 97d43340c6938dbd513c62e3528ae61f57cefe308cd950b0d0cf3f7a3a36993f *sparrow-1.8.2-aarch64.tar.gz ffb7f86e978ab312dcc169d7c70b33048256dcf3280aecb1cb9392124eac31b9 *sparrow-1.8.2-x86_64.tar.gz e69873062837f90745b384d53afeb590cb0058061da3148cbad35604b3e4b1bd *sparrow-server-1.8.2-1.aarch64.rpm 3fb4900e078427c230dd1372e1b56abdaa71653c5247d6ca4605e9fdda90bffe *sparrow-server-1.8.2-1.x86_64.rpm 6278fe3b8261576bb9e597ac0e1a5305781917a6716dfc8c5ebb8b244c1a8805 *sparrow-server-1.8.2-aarch64.tar.gz 0f2025a3fee1057fef763ff1ead471b4468766c0db99e07d8cd1de26e359852d *sparrow-server-1.8.2-x86_64.tar.gz c538a93d22698a46218859fbf936731484683e188da33a2e35dac053388a5e14 *sparrow-server_1.8.2-1_amd64.deb 817469b84741832d4b58b0f6305139cf740ba6b91ca9ff5e65dac75f1fa0221e *sparrow-server_1.8.2-1_arm64.deb ef461e5b75681e39fde235ee75d0bb23d4cfbeb30c312383f17596115d0a9188 *sparrow_1.8.2-1_amd64.deb f81b259799d3dbf7ac75555b59ac719256fcfacb716c653ca445f21f327add5c *sparrow_1.8.2-1_arm64.deb
You see a lot of stuff. You don't care about it for now since you want to keep your sanity. You simply run gpg --verify again and ...
$ ls total 106M -rw-r--r-- 1 ekzyis ekzyis 1.5K Feb 23 16:12 sparrow-1.8.2-manifest.txt -rw-r--r-- 1 ekzyis ekzyis 873 Feb 23 15:42 sparrow-1.8.2-manifest.txt.asc -rw-r--r-- 1 ekzyis ekzyis 106M Feb 23 20:17 sparrow-1.8.2-x86_64.tar.gz $ gpg --verify sparrow-1.8.2-manifest.txt.asc gpg: assuming signed data in 'sparrow-1.8.2-manifest.txt' gpg: Signature made Thu 18 Jan 2024 11:35:34 AM CET gpg: using RSA key D4D0D3202FC06849A257B38DE94618334C674B40 gpg: Good signature from "Craig Raw <craig@sparrowwallet.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: D4D0 D320 2FC0 6849 A257 B38D E946 1833 4C67 4B40
... it worked! You get "Good signature". That sounds good. But you wonder about the warning:
gpg: WARNING: This key is not certified with a trusted signature! gpg: There is no indication that the signature belongs to the owner.
Haven't you done your due diligence in the previous chapter? Well, I have and I still get this error for some reason, lol. Anyway ... you see that the Sparrow download page mentions exactly this case:
Note that you may get a message similar to the following:
gpg: WARNING: This key is not certified with a trusted signature! gpg: There is no indication that the signature belongs to the owner.
This simply means that you have not explicitly marked the public key as trusted in your own instance of GPG. In this case it is good practice to check the key against other sources, for example https://keybase.io/craigraw (click on the link next to the key icon to see the full public key). You can read more about validating keys in the GnuPG Privacy Handbook.
But we want to focus on verification for now. Never lose your sanity from multiple directions at once.
But aren't we already done? We got a good signature so we verified the software right?
You remember that the detached signature didn't look for the downloaded software since it didn't match the file without the .asc suffix. So something is off. You run another sanity check by deleting the software (or moving it somewhere else) and run gpg --verify for the fourth time:
$ ls total 8.0K -rw-r--r-- 1 ekzyis ekzyis 1.5K Feb 23 16:12 sparrow-1.8.2-manifest.txt -rw-r--r-- 1 ekzyis ekzyis 873 Feb 23 15:42 sparrow-1.8.2-manifest.txt.asc $ gpg --verify sparrow-1.8.2-manifest.txt.asc gpg: assuming signed data in 'sparrow-1.8.2-manifest.txt' gpg: Signature made Thu 18 Jan 2024 11:35:34 AM CET gpg: using RSA key D4D0D3202FC06849A257B38DE94618334C674B40 gpg: Good signature from "Craig Raw <craig@sparrowwallet.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: D4D0 D320 2FC0 6849 A257 B38D E946 1833 4C67 4B40
It still works. That was expected but it's weird.
We didn't even need the software for gpg --verify. How does that make sense? I thought we want to verify the authenticity and integrity of it?
You feel betrayed but continue reading the download page and find that it mentions this:
You have now verified the signature of the manifest file, which ensures integrity and authenticity of the manifest file - not the binaries! Next, depending on your operating system, you must re-compute the sha256 hash of the archive with shasum -a 256 <filename>. First, download the installation for your operating system (if you haven’t done so already). Then follow the steps below to compare it with the corresponding one in the manifest file, and ensure they match exactly.
Aha, so I verified the manifest file.
Looking at the manifest file again, you see that it contains a line for every binary that one can download. The binary that you downloaded is therefore also included (else your feelings of betrayal would have intensified):
ffb7f86e978ab312dcc169d7c70b33048256dcf3280aecb1cb9392124eac31b9 *sparrow-1.8.2-x86_64.tar.gz
You have some experience with hashes and can recognize hashes like ffb7f86e978ab312dcc169d7c70b33048256dcf3280aecb1cb9392124eac31b9 when you see them. But you didn't need to since the download page already mentioned that the file contains sha256 hashes.
It also mentioned that we should run shasum -a 256 <filename>. So we do exactly that and expect that it returns the same hash:
$ shasum -a 256 sparrow-1.8.2-x86_64.tar.gz ffb7f86e978ab312dcc169d7c70b33048256dcf3280aecb1cb9392124eac31b9 sparrow-1.8.2-x86_64.tar.gz
That looks about right! But it's pretty annoying to compare hashes by hand. The download page also has a solution for that. It mentions the following command for Linux users:
sha256sum --check sparrow-1.8.2-manifest.txt --ignore-missing
So we run this and expect more intimacy via hand-holding:
$ sha256sum --check sparrow-1.8.2-manifest.txt --ignore-missing sparrow-1.8.2-x86_64.tar.gz: OK
It says "OK". Well, that's not very intimate like what a lover probably would say but still sounds like a friend. Everything seems to be okay!

Conclusion

So what we just did was to basically verify the authenticity and integrity of the file that contained the hashes for all binaries with gpg --verify. When the hashes could be trusted, we could use them to make sure that the software was not tampered with. But why not simply provide a digital signature for the binary itself?
I actually don't know. But my educated guess is that it's related to convenience. Instead of providing a signature for every binary, the hashes are signed. Using sha25sum --check with --ignore-missing then simply ignores all files that don't exist. So I am basically guessing that there is no way to do something similar with digital signatures. Maybe someone knows more?

Wait ... but why (does it work)?

Essentially, if you believe in cryptographic hashes (like during bitcoin mining), you believe in digital signatures.
If you don't know what a hash is (and especially not cryptographic ones), read this. If you still don't know, you can ask questions in the comments. I am sure someone will be willing to answer them.
A digital signature is usually nothing else than a cryptographic hash that was "encrypted" with a secret key:
The private key can be used to create a digital signature for any piece of data using a digital signature algorithm. This typically involves taking a cryptographic hash of the data and operating on it mathematically using the private key. Anyone with the public key can check that this signature was created using the private key and the appropriate signature validation algorithm. A digital signature is a powerful tool because it allows you to publicly vouch for any message.
This means that during verification with the public key, we reverse the encryption with the private key to reveal the hash. Then, we hash the signed data ourselves and compare the hashes. If the hashes match, the integrity was verified and since public key cryptography was used, we also verified the authenticity of the hashes.

Makes sense? Still reading?
If so, you potentially even learned a lot about digital certificates work on accident. They are basically digital signatures that verify the identify of entities via trusted third parties (Certificate Authorities) and with more metadata associated. At least that's my simplistic explanation. But how the Public Key Infrastructure works is a topic for another day.

Footnotes

  1. I'll assume some basic Linux skills since those are more often than not very handy. You might even acquire the "required" Linux skills by accident while reading this just by the context the commands are used in—just like human languages.
  2. This is a step that is often overlooked or not even mentioned. That the public key is trustworthy is the foundation for this whole scheme. You SHOULD NOT simply trust keys. You should do some basic due diligence. Ask friends if they have the same public key. If you're fucked, at least they are fucked, too. Try to find key fingerprints and compare them using gpg --list-keys --keyid-format long. But surely someone else would have noticed if the key is compromised, right? Right? But I get it. It's just too convenient to simply trust keys in most cases.
@Natalia found a "fun read" in #437593:
Verifying signatures The Qubes OS Project uses digital signatures to guarantee the authenticity and integrity of certain important assets. This page explains how to verify those signatures. It is extremely important for your security to understand and apply these practices.
What digital signatures can and cannot prove Most people — even programmers — are confused about the basic concepts underlying digital signatures. Therefore, most people should read this section, even if it looks trivial at first sight.
Digital signatures can prove both authenticity and integrity to a reasonable degree of certainty. Authenticity ensures that a given file was indeed created by the person who signed it (i.e., that a third party did not forge it). Integrity ensures that the contents of the file have not been tampered with (i.e., that a third party has not undetectably altered its contents en route).
Digital signatures cannot prove, e.g., that the signed file is not malicious. In fact, there is nothing that could stop someone from signing a malicious program (and it happens from time to time in reality).
The point is that we must decide who we will trust (e.g., Linus Torvalds, Microsoft, or the Qubes Project) and assume that if a trusted party signed a given file, then it should not be malicious or negligently buggy. The decision of whether to trust any given party is beyond the scope of digital signatures. It’s more of a social and political decision.
Once we decide to trust certain parties, digital signatures are useful, because they make it possible for us to limit our trust only to those few parties we choose and not to worry about all the bad things that can happen between them and us, e.g., server compromises (qubes-os.org will surely be compromised one day, so don’t blindly trust the live version of this site), dishonest IT staff at the hosting company, dishonest staff at the ISPs, Wi-Fi attacks, etc. We call this philosophy distrusting the infrastructure.
By verifying all the files we download that purport to be authored by a party we’ve chosen to trust, we eliminate concerns about the bad things discussed above, since we can easily detect whether any files have been tampered with (and subsequently choose to refrain from executing, installing, or opening them).
However, for digital signatures to make sense, we must ensure that the public keys we use for signature verification are the original ones. Anybody can generate a cryptographic key that purports to belong to “The Qubes OS Project,” but of course only the keys that we (the real Qubes developers) generate are the genuine ones. The rest of this page explains how to verify the authenticity of the various keys used in the project and how to use those keys to verify certain important assets.
-- qubes-os.org, Verifying Signatures
Very good information about digital signatures and the involved trust. That's why I will pin this comment.
Big probs to @Natalia for finding and sharing this link!
reply
is it a feature or a bug? just learned how you can zap the pinned comment 😂
go back to where you were @, but then how the others can zap the pinned comment?
reply
111 sats \ 1 reply \ @ek OP 24 Feb
is it a feature or a bug? just learned how you can zap the pinned comment
it's an unintended secret
but then how the others can zap the pinned comment?
you can click on the time to make the comment the root item:
reply
new hack! 👀👌🏽
reply
1191 sats \ 1 reply \ @siggy47 24 Feb
Damn, @ek. This is what I call proof of work. Great post. I have actually done this a few times. Next time I won't skip the verifying.
reply
195 sats \ 0 replies \ @ek OP 24 Feb
Thanks but I actually hate it when I just want to create a short post and then this comes out after a few hours haha
I have actually done this a few times. Next time I won't skip the verifying.
Yeah, I feel like one should do it at least once for each software. A bit like staying seated in the cinema during the credits after a great movie to show some respect even though you don't really read them haha
reply
This is great, and timely. Thanks!
When I started caring about this it brought me down a btc-like rabbit hole, where you have to really get solid about your notion of identity, and confront the relationship between identity and social proof. It turned very philosophical for me, and weirdly fun.
reply
practice 1. verifying the GPG Suite
  1. found the public key in https://keybase.io/gpgtools and it's the same as the one showing in the site foot.
curl https://keybase.io/gpgtools/pgp_keys.asc | gpg --import
Imported the key and marked full trust.
  1. verified the signature file.
8C31 E5A1 7DD5 D932 B448 FE1D E8A6 6448 0D9E 43F5
but it's showing one of the expired keys, I think it still meant the file is OK.
  1. verified the hashes.
cd Downloads echo "57468a4adc55d954ead4fe1f88b07eac1b70ada40fcbc810765fd521ef21eef1 GPG_Suite-2023.3.dmg" | shasum -a 256 -c - GPG_Suite-2023.3.dmg: OK
am I doing it correctly? 👀
reply
1175 sats \ 1 reply \ @ek OP 24 Feb
Ok haha, verifying the tool you use to verify is a funny special case. But very good idea and this gets deep and philosophical fast. 😔
but it's showing one of the expired keys, I think it still meant the file is OK.
I also think so
am I doing it correctly? 👀
Yes, you are doing great!
reply
well, it needs to start with verifying the tool before verifying other things. 🤓
and in this case, the software didn't sign too? and how can I tell is it sign or not? ( when do I need to do the sha256sum --check step )
reply
This post reminds me how far you actually need to go to do a full, like really full, verification. I'll see if i can find an article on this topic. E.g. can you trust the compiler that you use to compile the code you've verified to be legit and downloaded? Any many more questions like that.
reply
More accurately: it reveals that trust is perpetual and ubiquitous. There's no such thing as 'trustless'. It's only a question of exactly who / what you trust, and exactly what that trust is based on.
reply
A lot of Bitcoiners have yet to learn this
reply
However, the instructions to download the public key are provided at the same location. So couldn't they also have been replaced?
yes, that's what I was thinking!
I'll assume some basic Linux skills since those are more often than not very handy. You might even acquire the "required" Linux skills by accident while reading this just by the context the commands are used in—just like human languages
agree, the art of learning is actually not focus on learning but solving problems!
If you're fucked, at least they are fucked, too.
what kind of friends are these!? 😂
and wow, thanks for the explanation! I see I'm missing quite some steps now,
  1. get the verified public key from different sources
  2. verify the signature of the file which contain the hashes
  3. verify the hashes
hmmmm, people always say don't trust but verify, but the art of verifying is not much being discussed, like a. what to verify b. how to verify; I will do more practice today and come back for feedback. 👀
reply
473 sats \ 0 replies \ @Fabs 24 Feb

Interesting.

I won't say more because it's way over my head, but: "👍" from the bottom of my heart, keep it up.
reply
practice 2. verifying the Electrum Wallet
  1. found the public key from https://github.com/spesmilo/electrum/blob/master/pubkeys/ThomasV.asc
Imported the key, also there are other devs are listed on the site.
  1. verified the file.
gpg --verify electrum-4.5.3.dmg.asc gpg: assuming signed data in 'electrum-4.5.3.dmg' gpg: Signature made Fri 23 Feb 12:32:06 2024 +03 gpg: using RSA key 637DB1E23370F84AFF88CCE03152347D07DA627C gpg: Good signature from "Stephan Oeste (it) <it@oeste.de>" [unknown] gpg: aka "Stephan Oeste (Master-key) <stephan@oeste.de>" [unknown] gpg: aka "Emzy E. (emzy) <emzy@emzy.de>" [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: 9EDA FF80 E080 6596 04F4 A76B 2EBB 056F D847 F8A7 Subkey fingerprint: 637D B1E2 3370 F84A FF88 CCE0 3152 347D 07DA 627C gpg: Signature made Fri 23 Feb 03:00:55 2024 +03 gpg: using RSA key 0EEDCFD5CAFB459067349B23CA9EEEC43DF911DC gpg: Good signature from "SomberNight/ghost43 (Electrum RELEASE signing key) <somber.night@protonmail.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: 0EED CFD5 CAFB 4590 6734 9B23 CA9E EEC4 3DF9 11DC gpg: Signature made Fri 23 Feb 02:46:47 2024 +03 gpg: using RSA key 6694D8DE7BE8EE5631BED9502BD5824B7F9470E6 gpg: Good signature from "Thomas Voegtlin (https://electrum.org) <thomasv@electrum.org>" [unknown] gpg: aka "Thomas Voegtlin <thomasv1@gmx.de>" [unknown] gpg: aka "ThomasV <thomasv1@gmx.de>" [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: 6694 D8DE 7BE8 EE56 31BE D950 2BD5 824B 7F94 70E6
one thing really strange is that when I tried this again, it says
gpg: can't open 'electrum-4.5.3.dmg.asc': No such file or directory gpg: verify signatures failed: No such file or directory
  1. I can't find the SHA256 to continue 😳
reply
  1. found the public key from https://github.com/spesmilo/electrum/blob/master/pubkeys/ThomasV.asc
Imported the key, also there are other devs are listed on the site.
Good, I think using Github as the source of trust is okay. But remember: the more sources that say that this is indeed the correct key, the better!
one thing really strange is that when I tried this again, it says
gpg: can't open 'electrum-4.5.3.dmg.asc': No such file or directory gpg: verify signatures failed: No such file or directory
Mhh, and you are sure you didn't (remove) the file? Did you run gpg --verify in the correct folder?
  1. I can't find the SHA256 to continue 😳
If the software you downloaded was signed, then you don't need separate hashes. The signature contains the hash to verify integrity. I can tell from your comment that this is the case for Electrum since the signature is named electrum-4.5.3.dmg.asc and the software is in electrum-4.5.3.dmg.
Sparrow Wallet was just a special case where not the software was signed but the hashes. Then you need to run another command (sha256sum --check <hashfile> --ignore-missing) to verify the software.
I mentioned that I don't know why Craig did it like this, I only had an educated guess:
Conclusion
So what we just did was to basically verify the authenticity and integrity of the file that contained the hashes for all binaries with gpg --verify. When the hashes could be trusted, we could use them to make sure that the software was not tampered with. But why not simply provide a digital signature for the binary itself?
I actually don't know. But my educated guess is that it's related to convenience. Instead of providing a signature for every binary, the hashes are signed. Using sha256sum --check with --ignore-missing then simply ignores all files that don't exist. So I am basically guessing that there is no way to do something similar with digital signatures. Maybe someone knows more?
reply
wait, so when the software was signed all you need to do is finding the correct public key ( the more sources suggesting the same key the better ), and then verify the asc? that's all?
reply
480 sats \ 37 replies \ @ek OP 24 Feb
Yes. The "asc" is the (detached) signature.
The hardest part is verifying the public key but most people just skip that lol
reply
how hard can it be, all you need to do is to search. 😂
reply
346 sats \ 28 replies \ @ek OP 24 Feb
To be fair, I think if the instructions mention to import the key from a site like Keybase like Sparrow does, I think it's fine. Most important thing is to not import the public key from the same site you received everything else and I think if people just follow instructions, they automatically do that.
It just makes me feel uneasy if people are not aware that this is important. The why's and so on.
reply
It just makes me feel uneasy if people are not aware that this is important.
like @DarthCoin say - education is key 🔑
reply
Haha yes. Like a secret key hidden in plain sight.
now I finally understand what you mean here, why not just put each dev's key in GitHub 😨
reply
Best way is to spread your key fingerprint around imo.
If you only use one site as the source of trust, it's a single point of failure. Even if it's Github.
I have to do that myself, still figuring things out around PGP keys
reply
agree, and some of them are quite hard to search, e.g. Mullvad VPN, I couldn't find it in other places besides their site, madness.
reply
I don't see a key fingerprint there 👀
deleted by author
reply
This is fantastic. To the top with you!
reply
new questions 👀
  • why some softwares are encouraging people to verify, or at least point it out how, but some are not even bother mentioning anything?
  • the GPG suit is quite interesting, once you export the private key you still need the PW that you set before to import it, what would happen if you lost that? but isn't the private key like the seeds which could be used independently , or is it because I'm using a third party tool so I need the PW to unlock the key?
  • going down this verifying rabbit hole, now I wonder what's the safer way to download addons, e.g. Alby extension or Bitwarden.
reply
245 sats \ 0 replies \ @ek OP 25 Feb
why some softwares are encouraging people to verify, or at least point it out how, but some are not even bother mentioning anything?
Different priorities, I guess
the GPG suit is quite interesting, once you export the private key you still need the PW that you set before to import it, what would happen if you lost that? but isn't the private key like the seeds which could be used independently , or is it because I'm using a third party tool so I need the PW to unlock the key?
It's because your key was encrypted and the password is required for decryption. It's also recommended to set a password. So yes, it's like seeds that can be used independently—at least I would think that's how GPG suite implemented it but can't verify, since I don't have macOS. Therefore, if you lose the password, you lose the key. So use password manager to use strong passwords without forgetting them or this method:
I would still recommend using a password manager but seems like you already do
going down this verifying rabbit hole, now I wonder what's the safer way to download addons, e.g. Alby extension or Bitwarden.
Mhh, good question. I think you only have two options: use the official store to which Bitwarden themselves link to here or build the extension yourself but I imagine that's going to be pretty difficult since it's only intended for development.
reply