If we import the public key of the person who made a signature for a file and we just tried to verify the signature of that file with:
gpg --verify some-download.zip.asc some-download.zip
and saw a warning like:
gpg: WARNING: This key is not certified with a trusted signature!
gpg: There is no indication that the signature belongs to the owner.
it likely means we haven't signed the public key of the signature-maker. Signing someone else's public key is GPG's way to indicate we think the key is accurate, authentic, valid. (There is also a "web of trust" that can avoid this warning situation, but that's very likely not your issue/situation.)
The Fix
To sign/certify/validate that signer's key after we have imported their public key and after we've set trust on their key (some value between none, marginal, fully, ultimate) we need to:
gpg --lsign-key <signers-pubkey-ID>
This is us using our private GPG key to personally sign and CERTIFY that we trust/validate/vouch/certify/solemnly-swear-as-legit this signer's key and the signatures they make with their key belong to the person named/identified by the key.
If there are multiple emails/identities associated with the signer's public key we'll be asked:
Really sign all user ID's? (y/N)
Answer y
and hit return.
We'll be asked: Really sign? (y/N)
.
Answer y
and hit return.
The above --lsign-key
is to sign/vouch for a public key only locally on our own machine. If we want to do so publicly and upload our vouching to a keyserver we can use --sign-key
.
Notes / Thoughts
When we --lsign-key
/ --sign-key
, we should be very sure that that key belongs to the person we think it belongs to / is listed as the owner. It's us putting our personal rubber-stamp on that key as being legit & owned by the person listed.
No one should be able to fake our certification/validation when we sign someone else's public key, because we were required to use our private key to certify/validate. A private key should (hopefully) be only accessible to the owner and (hopefully) password protected and therefore cannot be faked and thus we have personally vouched for this other person's public key & signatures produced from that key.
"trust" vs "validity"
The editing of "trust" (setting it from none to ultimate) using gpg --edit-key <some-key-ID>
then setting trust from 0 to 5 isn't about how much we trust that key. That trust is how much we trust the owner of that key to vouch for others and their keys (creating a "web of trust").
It's unfortunate that the wording around trust and validity in GPG documentation/commands is confusing. It's confusing when we set "trust" of a public key and yet it doesn't affect our trust of that exact key, but rather, how much we value (trust) that person's validation of yet other keys.
When we set "trust" in GPG, we (in our own heads) say:
"I (Billy) trust Jane ultimately."
GPG interprets that as:
"Billy trusts Jane to the ultimate degree to vouch for GPG keys that she herself has signed as valid."
When what we really wanted GPG to hear was:
"I (Billy) ultimately trust this key is Jane's key."
To get GPG to understand that, we need to:
--sign-key
or --lsign-key
Jane's public key, not trust
her.
Example
Freshly Imported Key
Import the public key of Other User.
$ gpg --import OtherU_pubkey.asc
gpg: key 70E670E670E670E6: public key "Other User (https://somesite.org) <[email protected]>" imported
gpg: Total number processed: 1
gpg: imported: 1
If we edit the key now, it will have no trust, no validity:
$ gpg --edit-key 70E670E670E670E6
pub rsa4096/70E670E670E670E6
created: 2011-06-15 expires: never usage: SC
trust: unknown validity: unknown
sub rsa4096/CD84CD84CD84CD84
created: 2011-06-15 expires: never usage: E
[ unknown] (1). Other User (https://somesite.org) <[email protected]>
[ unknown] (2) OtherU <[email protected]>
[ unknown] (3) Other User <[email protected]>
Notice three things: trust: unknown
and validity: unknown
and [ unknown ]
.
Trust ≠ Validity
If we set trust
to 4
, the key will show trust: full
but validity
will remain unknown
.
gpg> trust
pub rsa4096/70E670E670E670E6
created: 2011-06-15 expires: never usage: SC
trust: unknown validity: unknown
sub rsa4096/CD84CD84CD84CD84
created: 2011-06-15 expires: never usage: E
[ unknown] (1). Other User (https://somesite.org) <[email protected]>
[ unknown] (2) OtherU <[email protected]>
[ unknown] (3) Other User <[email protected]>
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? 4
pub rsa4096/70E670E670E670E6
created: 2011-06-15 expires: never usage: SC
trust: full validity: unknown
sub rsa4096/CD84CD84CD84CD84
created: 2011-06-15 expires: never usage: E
[ unknown] (1). Other User (https://somesite.org) <[email protected]>
[ unknown] (2) OtherU <[email protected]>
[ unknown] (3) Other User <[email protected]>
Please note that the shown key validity is not necessarily correct
unless you restart the program.
Note that the key now reads trust: full
validity: unknown
. That validity: unknown
is what is causing the WARNING in the question.
The [ unknown]
s also indicate we haven't validated the key / its associated user IDs (identified by names, emails, websites, etc.).
If we sign
(or lsign
i.e. local sign) the key, its validity will go full
:
gpg> lsign
Really sign all user IDs? (y/N) y
pub rsa4096/70E670E670E670E6
created: 2011-06-15 expires: never usage: SC
trust: full validity: unknown
Primary key fingerprint: 70E6 70E6 70E6 EE56 31BE D950 70E6 70E6 70E6 70E6
Other User (https://somesite.org) <[email protected]>
OtherU <[email protected]>
Other User <[email protected]>
Are you sure that you want to sign this key with your
key "Me MyKey <[email protected]>" (L0LCAT5HA58URG3R)
The signature will be marked as non-exportable.
Really sign? (y/N) y
gpg> save
Remember to save
which will also quit you out of GPG.
If you edit the key again:
$ gpg --edit-key 70E670E670E670E6
pub rsa4096/70E670E670E670E6
created: 2011-06-15 expires: never usage: SC
trust: full validity: full
sub rsa4096/CD84CD84CD84CD84
created: 2011-06-15 expires: never usage: E
[ full ] (1). Other User (https://somesite.org) <[email protected]>
[ full ] (2) OtherU <[email protected]>
[ full ] (3) Other User <[email protected]>
we'll see trust: full
and validity: full
.
Also the square brackets before the user IDs are now all [ full ]
.
When we now check signatures for this public key, we'll not see warnings of certification/validity. (If the file was signed by multiple keys, you will see warnings of Can't check signature: No public key
for those other signers.)
$ gpg --verify some-download.zip.asc some-download.zip
gpg: Signature made Thu 17 Aug 12:09:32 2023 PDT
gpg: using RSA key 70E670E670E6EE5631BED95070E670E670E670E6
gpg: Good signature from "Other User (https://somesite.org) <[email protected]>" [full]
gpg: aka "OtherU <[email protected]>" [full]
gpg: aka "Other User <[email protected]>" [full]