Intro
This’ll be a quick one. I’m not going to explain gpg here, I have heaps on that already.
In this guide, I’ll show you how to first sign a file with your private key. I’m also assuming you already have a private key, see this guide if not.
What is the point? Well, if you’re a developer, this is essential to prove which version (down to the bit) is truly the version that you’re releasing. Any edits to the software will invalidate the signature, alerting the user to a problem (man-in-the-middle attacks are one example).
Why is this needed for open source software? Isn’t it all open to read anyway? Well, sort of. The code can be read, but the binary files (the executables) are in MACHINE CODE, which is not human-readable. The developer often compiles the program from the readable code and produces a nice, easy-to-use installation file (machine code, binary file, executable). You are actually trusting the developer that they are compiling the code that everyone can read, and not making dodgy secret edits and compiling nefarious software. It’s important to appreciate just where your trust lies.
The alternative is to compile the code yourself (can be hard). If you do that, then you are not trusting the developer’s binary files. What are you trusting? You’re trusting that the code is good and someone else has gone through it and eliminated anything nefarious, or that the developer wouldn’t risk putting something nefarious for all/anyone to find – Still trusting. To eliminate that, read the code yourself. But then there are programs the developer uses, available to the operating system etc. You can not verify everything yourself, you can not make your own microprocessor etc – there is always an element of trust; just do your best. The wrong type of trust is when you can feasibly do something to eliminate trust, but you’re being lazy. This just puts you at unnecessary increased risk. So don’t be lazy.
Private Keys
The first thing to do is to list the private keys you have on your system. These are your OWN private keys, which you made earlier, not the public keys you imported.
gpg –list-secret-keys
If you have only one private key on the system, you can skip this as the computer will just use the only one you have and you won’t need to specify.
Signing
Next, navigate to the directory where the file to sign is, so you can avoid typing paths in the signing command.
Then, from the list command above, you can identify a unique feature like the fingerprint or email address. Use it after ‘–local-user’ to select that key. If you only have one key anyway, omit the ‘–local-user’ option (and the text after, so remove the email address); you’ll get a warning, but it’ll still work.
gpg --local-user 'email@example.com' --armor --detach-sign --output program.zip.sig program.zip
The above command is on one line, watch out for where the spaces go, they matter, and obviously call program.zip.sig anything you want, and program.zip is the document or program that you’re signing. The spelling of that has to be perfect.
Once done, you get a signature file called ‘program.zip.sig’.
You can actually include the message with the signature, you just have to replace ‘–detach-sign’ with ‘–clearsign’.
You can also pipe text to the signing command instead of using a file, eg
echo "your text to sign" | gpg --armor --clearsign
The above command will give you the message and the signature in one, but it prints to the screen only. If you want it to a file, add ‘–output’ and then your chosen filename.
Verifying
Now anyone can verify that by using 3 things…
- Your public key
- The signature file
- The program/document (ie the message)
The public key is first imported…
gpg --import YourPublicKey.pgp
Then anyone verifying needs to download your signature file, and message file, and run this command…
gpg --verify program.zip.sig program.zip
Sometimes they can leave off ‘program.zip‘ and the computer can guess instead, especially if the file names are similar. Obviously, the two files have to be in the same directory; otherwise, they have to give the command the full path of the files.
The result will have “Good Signature” in the output (success) or “Bad Signature” (fail). There’ll also be a warning at the bottom, which is fine to ignore – see next section on trust levels, if you can’t let it go.
That’s it. Go practice.
Trust Levels
More info about that warning at the end…
Each key you upload as a certain level of trust that can be attached to it, the default being none. What trust? The trust you assign that the key truly belongs to the person who it is supposed to belong to. You might meet with the person and verify what the key’s fingerprint is (fingerprint is like a mini hash – what’s a hash? See here). Because you met the person, you can be 100% it really is there key. Now, you can assign high trust to the key like this…
First, look at the fingerprint:
gpg --fingerprint key-id
Here, ‘key-id’ can be something that identifies the key in your list, like the email (note: it doesn’t even need to be the whole address, just enough that it’s not ambiguous to the computer).
If the fingerprint is the one you are after, then do this:
gpg --edit-key key-id
You’ll get an interactive prompt. Type trust and <enter>. Then choose. Then type save and <enter>.
That’s it. Now you have assigned your selected level of trust to a key in your keyring.
Tips
If you find this resource useful, and you’d like to support what I do for Bitcoin, you can donate some sats here:
On-chain or Lightning
