From the gpg
manual:
--refresh-keys Request updates from a keyserver for keys that already exist on the local keyring. This is useful for updating a key with the latest signatures, user IDs, etc. Calling this with no arguments will refresh the entire keyring.
But there is no claim about how secure this is.
So the questions is:
Is it secure to use gpg --refresh-keys
to refresh keys from a malicious keyserver?
This implies the answer to the question, where you can get more information about why this process is considered secure, as without such documentation, the update process is not trustworthy.
Here is the scenario:
Somebody with high power (say somebody between the power of Google and the power of NSA) hacks into a keyserver. The one has enough power to run cryptoanalysis against all keys on the keyserver and is able to break everything which is not cryptographically secure in the current common sense including the forseeable future.
Hence RSA 768 can be broken by the attacker, RSA 4096 not yet, MD5 can be broken with known plaintext (so for any MD5 the attacker can create a document with this MD5), SHA1 can be broken with precomputed collision attack (so an arbitrary SHA1 cannot be broken, but the attacker can create 2 documents with the same SHA1) and so on.
Also this attacker is the perfect MitM between you and the keyserver, because the attacker has 101% control of the keyserver (more than the rightful owner).
Does such a malicious keyserver impose any threat to the the --refresh-keys
feature or not?
If not, why not? Where is the proof for this? Where is it documented that the command is safe to use?
Assumptions:
The attacker is capable of state-of-the-art cryptoanalysis available to us in 2020 today, on a level of Bruce Schneier.
There is no secret knowledge of the attacker. So the attacker neither has unknown knowledge except what is our deepest public knowledge in the cryptoanalysis area today (in 2020).
The attacker uses hardware of the edge of state of the art today. So if there are - today - known how we could build special hardware like FPGA or render engines to break security, the attacker already has it available as of today.
The attacker does not use hardware from the future, so no design we do not already know how to build or really could manufacture today. But he has access to hardware of FABs which are currently in planning already (so we know how to manufacture, but currently are just lacking the FABs for this. So the attacker has access to all such technology we can build in a few years with the knowledge of today).
The attacker has the available computing power and storage capacity of 2030, so can mount attacks already today which would be very expensive with our today's computing power. Say, the attacker is able to use the estimated computing power today which can be bought in 2030 for $10,000,000 (ten million dollars) which should cost more than 1 billion dollars today. So the power is around what the clouds of Google/AWS/Azure offer for extreme customers, so is just a bit less than what the NSA could do.
There is no zero-day exploit which imposes a danger to the GPG-client doing the request against the malicious keyserver. Also the computer used and the OS used are secure with no backdoors nor remote exploits.
My current fallback to --refresh-keys
:
- Download the new key
- Compare the cryptographic hash of both, the old and the new key (output of
gpg key.pgp
) - Only update the old key if both hashes are the same
Perhaps --refresh-keys
does exactly that? Why doesn't it tell so?
Example:
$ gpg yarnpkg.gpg.pub
gpg: WARNING: no command supplied. Trying to guess what you mean ...
pub rsa4096 2016-10-05 [SC]
72ECF46A56B4AD39C907BBB71646B01B86E50310
uid Yarn Packaging <yarn@dan.cx>
sub rsa4096 2016-10-05 [E]
sub rsa4096 2016-10-05 [S] [expired: 2017-10-05]
sub rsa4096 2016-10-30 [S] [expired: 2019-01-01]
sub rsa4096 2017-09-10 [S] [expired: 2019-01-01]
sub rsa4096 2019-01-02 [S] [expires: 2021-02-03]
sub rsa4096 2019-01-11 [S] [expires: 2021-02-03]
$ gpg /etc/apt/trusted.gpg.d/yarnpkg.gpg
gpg: WARNING: no command supplied. Trying to guess what you mean ...
pub rsa4096 2016-10-05 [SC]
72ECF46A56B4AD39C907BBB71646B01B86E50310
uid Yarn Packaging <yarn@dan.cx>
sub rsa4096 2016-10-05 [E]
sub rsa4096 2016-10-05 [S] [expired: 2017-10-05]
sub rsa4096 2016-10-30 [S] [expired: 2019-01-01]
sub rsa4096 2017-09-10 [S] [expired: 2019-01-01]
sub rsa4096 2019-01-02 [S] [expired: 2020-02-02]
sub rsa4096 2019-01-11 [S] [expired: 2020-02-02]
Here we see that 72ECF46A56B4AD39C907BBB71646B01B86E50310
is the same on both.
Hence the new one (with subkey which expires 2021) can be considered a safe successor to the old own (with subkey which already is expired).
But this is a manual and clumsy way of updating. And I cannot see that --refresh-keys
has - at least - the same safe properties as the manual process, if the manual process is properly done.
Notes:
In this case we do not have other information available like the web-of-trust etc.
And it is not the question if I can trust the old key. The question is, can I trust the new key after
--refresh-keys
at the same level as after the update example above.I tried to google for
is gpg refresh-keys secure
and similar, but this did not reveal any trace of an answer to me nor any documentation about what--refresh-keys
is supposed to do.I even tried to understand the source, but failed to build up enough understanding, what this command exactly does and I cannot make sure that it cannot have some bad sideffect (possibly unknown to me due to lack of some details of the GPG source code).
Also please forgive me that I lack the ability to shorten this answer without leaving out perhaps important details or nuances as English is not my native language.