Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

So I received a gpg-signed email, can I trust it?

5 views
Skip to first unread message

Enrico Zini

unread,
Jul 8, 2016, 5:30:03 AM7/8/16
to
Hello,

given that it is now possible to generate arbitrary short key ID
collisions[1], and that it's now computationally feasible to at least
generate a pair of keys with colliding long key IDs, I'd like to rethink
practices and tools.

In the spirit of "first get to do it, then document it, then automate
it", I'd like to begin with a simple use case:

So I received a gpg-signed email, can I trust it?

I'll write here my take on it and request your comments on it, to see if
there are any gaps.

Take for example this file, and an empty keyring:

$ mkdir /tmp/keyring
$ chmod 0700 /tmp/keyring
$ echo "keyserver hkp://keys.gnupg.net" >> /tmp/keyring/gpg.conf
$ cat /tmp/testmessage
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Fri Jul 8 11:03:02 CEST 2016: this is a test message
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1

iQIcBAEBCAAGBQJXf2xGAAoJEAPWVoyDcnWpzsoP/Aiw9y3D7qM/8aIjTuTakXG1
dbDi/7lIrWx2bvFFVAFY27q9l6UKF97nXym28ceatpPhYyeuUbSms12btY3kQ796
nEF81oLIHonayD6QOOSj2SrJIgl2B5oYSg/fxsq+bUBmcY9T3aHPsgGlSU7+to2b
ohv9D/Big3H2hWx0PPfhnLsCXLcNXFmUt83hsrrgUQvRA9oh7FjKBjbOYyLd4hBN
ejvnaf5PWuhPfWtK1mMpTEExn6V5i498+PxGojXLzapbtGEcybqfdvqlbtqii2LP
0dg4UwPnGdzZPUHHRbUwslLoPRb9KCspxlAE1U707NH+4Y3/4GMi/lhnfp/qxpMF
OKey0STi1pIJbn5SbG5GHlQD+1zbypelr4UnvOEZsYNcxkN1iduA5jL4IreQ2KqU
d/bVplK1w9i766ZgLI69A1TuRneKiRJTNur0UOwQZv0zonlGhIlSKi1IoMCtrKtN
jXTwALyUj5xUyNYAwqwR9I93wAcVVWzJbHB6DSCYa11AIkZV7Lnvz6A+dcNOdX21
3mhsjRqM5U28fBk5pdGj/MkjJyL4aegmzFBiImUQtV8gIL5HGmI2yxlLvIEx7O7z
PUrOKZLrHflCZ0kZOty5njnZ2ep2rRQNEdT4mD8SuKKt6vfpQdzUQxTZoRgOHYA2
Skl15idSonqVP370zzDf
=DKdd
-----END PGP SIGNATURE-----

gpg --verify tells me of a short key ID:

$ gpg2 --homedir /tmp/keyring/ --verify /tmp/testmessage
gpg: keybox '/tmp/keyring//pubring.kbx' created
gpg: Signature made Fri 08 Jul 2016 11:03:02 CEST using RSA key ID 837275A9
gpg: Can't check signature: No public key

I can switch to long key IDs, but I still get something that can match
multiple keys:

$ echo "keyid-format long" >> /tmp/keyring/gpg.conf
$ gpg2 --homedir /tmp/keyring/ --verify /tmp/testmessage
gpg: Signature made Fri 08 Jul 2016 11:03:02 CEST
gpg: using RSA key 03D6568C837275A9
gpg: Can't check signature: No public key

So let's assume long key IDs give me only a false sense of security and
go ahead without "keyid-format long". I'll download the key used to sign
the message:

$ gpg2 --homedir /tmp/keyring/ --recv 837275A9
gpg: /tmp/keyring//trustdb.gpg: trustdb created
gpg: key E7AD5568: public key "Enrico Zini <enr...@enricozini.org>" imported
gpg: no ultimately trusted keys found
gpg: Total number processed: 1
gpg: imported: 1

In this case I've been lucky, because there were no collisions on the
short key ID of my signing subkey, but I cannot rely on having only the
right key in the keyring at this point. For example:

$ gpg2 --homedir /tmp/keyring/ --recv A7457645
gpg: key A7457645: public key "Piotr Ozarowski <oza...@gmail.com>" imported
gpg: key A7457645: public key "Piotr Ozarowski <oza...@gmail.com>" imported
gpg: no ultimately trusted keys found
gpg: Total number processed: 2
gpg: imported: 2

Now I have one or more keys, I can verify the message:

$ gpg2 --homedir /tmp/keyring/ --verify /tmp/testmessage
gpg: Signature made Fri 08 Jul 2016 11:03:02 CEST using RSA key ID 837275A9
gpg: Good signature from "Enrico Zini <enr...@enricozini.org>" [unknown]
gpg: aka "Enrico Zini <enr...@debian.org>" [unknown]
gpg: aka "Enrico Zini <enr...@truelite.it>" [unknown]
gpg: aka "Enrico Zini <enr...@enricozini.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: 1793 D6AB 7566 3E6B F104 953A 634F 4BD1 E7AD 5568
Subkey fingerprint: 1CC0 1267 007F ABE6 5846 6857 03D6 568C 8372 75A9

gpg2 tells me that the signature is Good (that is, the message is the
same that has been signed and has not been tampered with), and it has
been verified as having been made with the key 1793D6AB75663E6BF104953A634F4BD1E7AD5568.

I know that the message hasn't been tampered with, but it can still be a
message from the attacker that generated the colliding key, so now I
neeed to find out what I can tell about the owner of key
1793D6AB75663E6BF104953A634F4BD1E7AD5568. I made an attempt at this at
http://www.enricozini.org/blog/2016/debian/verifying-gpg-keys/


Enrico

[1] https://evil32.com/
[2] https://www.ietf.org/mail-archive/web/openpgp/current/msg07195.html
https://github.com/coruus/cooperpair
--
GPG key: 4096R/634F4BD1E7AD5568 2009-05-08 Enrico Zini <enr...@enricozini.org>
signature.asc

Jakub Wilk

unread,
Jul 8, 2016, 7:40:02 AM7/8/16
to
* Enrico Zini <enr...@enricozini.org>, 2016-07-08, 11:21:
> $ mkdir /tmp/keyring
> $ chmod 0700 /tmp/keyring

This way of creating a directory inaccessible to other is racy. Between
mkdir and chmod calls, the directory could be opened by an attacker (and
then kept open forever). A non-racy way looks like this:

$ mkdir -m 0700 foobar


And you really shouldn't use /tmp as a personal scratch space.
/tmp is word-writable and therefore not suitable for this purpose.

(Yes, I realize that these are just examples. But let's not teach people
bad habits.)

--
Jakub Wilk

Simon Richter

unread,
Jul 8, 2016, 8:40:02 AM7/8/16
to
Hi Enrico,

On 08.07.2016 11:21, Enrico Zini wrote:

> given that it is now possible to generate arbitrary short key ID
> collisions[1], and that it's now computationally feasible to at least
> generate a pair of keys with colliding long key IDs, I'd like to rethink
> practices and tools.

With the web of trust, in principle there shouldn't be a problem.

I have a valid trust path to Piotr's correct key. I don' have any to the
fake key, because no one I trust has signed a key from the evil32 set.

What could be improved would be detection of new signatures under fake
keys. I've filed Debian bug #830479 about a possible solution.

Simon

signature.asc

Enrico Zini

unread,
Jul 8, 2016, 9:00:02 AM7/8/16
to
On Fri, Jul 08, 2016 at 02:33:54PM +0200, Simon Richter wrote:

> > given that it is now possible to generate arbitrary short key ID
> > collisions[1], and that it's now computationally feasible to at least
> > generate a pair of keys with colliding long key IDs, I'd like to rethink
> > practices and tools.
>
> With the web of trust, in principle there shouldn't be a problem.
>
> I have a valid trust path to Piotr's correct key. I don' have any to the
> fake key, because no one I trust has signed a key from the evil32 set.

What if you received a message signed with key 9F6C6333?

That is, what do you do (please list the practical steps) to validate a
signature that is a few steps away from your key in the WoT?


Enrico
signature.asc

Jakub Wilk

unread,
Jul 8, 2016, 11:00:03 AM7/8/16
to
* Simon Richter <s...@debian.org>, 2016-07-08, 14:33:
>>given that it is now possible to generate arbitrary short key ID
>>collisions[1], and that it's now computationally feasible to at least
>>generate a pair of keys with colliding long key IDs, I'd like to
>>rethink practices and tools.
>
>With the web of trust, in principle there shouldn't be a problem.
>
>I have a valid trust path to Piotr's correct key. I don' have any to
>the fake key, because no one I trust has signed a key from the evil32
>set
...yet.

Given that many crypto tools have --feel-free-to-shoot-me-in-the-foot as
the default, and some even don't have --do-not-shoot-me-in-the-foot as
an option (see #800134), it's only a matter of time before someone slips
up.

Or maybe it's already happened? Check out debian-hiding-problems@, er, I
mean debian-private@ archives.

--
Jakub Wilk

Guilhem Moulin

unread,
Jul 8, 2016, 11:20:03 AM7/8/16
to
Hi Enrico,

On Fri, 08 Jul 2016 at 11:21:27 +0200, Enrico Zini wrote:
> gpg --verify tells me of a short key ID:

In fact the issuer subpacket is 8-bytes long [0], hence contains the
long key ID of the signer, as seen using ‘--list-packets’:

~$ gpg --list-packets </tmp/testsignature
# off=0 ctb=89 tag=2 hlen=3 plen=540
:signature packet: algo 1, keyid 03D6568C837275A9
version 4, created 1467968582, md5len 0, sigclass 0x01
digest algo 8, begin of digest ce ca
hashed subpkt 2 len 4 (sig created 2016-07-08)
subpkt 16 len 8 (issuer key ID 03D6568C837275A9)
data: [4092 bits]

(Where ‘/tmp/testsignature’ is the signature part of your previous
‘/tmp/testmessage’.) It's unfortunate that gpg used to only show the
second half of the subpacket (the “short key ID”) by default. However
2.1.13 introduces a new ‘--keyid-format=none’ - which is the new default
— to stop using keyids whenever possible: instead, the key fingerprint
is shown when available (e.g., for keys in the keyring); otherwise it
falls back to the “long key ID”.

~$ gpg --version | head
gpg (GnuPG) 2.1.13
libgcrypt 1.7.1-beta
~$ rm /tmp/keyring/gpg.conf
$ gpg --homedir /tmp/keyring --verify /tmp/testmessage
gpg: Signature made Fri 08 Jul 2016 11:03:02 AM CEST using RSA key ID 03D6568C837275A9
gpg: Can't check signature: No public key
$ gpg --homedir /tmp/keyring --keyserver=hkps://hkps.pool.sks-keyservers.net --keyserver-options=auto-key-retrieve --verify /tmp/testmessage
gpg: Signature made Fri 08 Jul 2016 11:03:02 AM CEST using RSA key ID 03D6568C837275A9
gpg: requesting key 03D6568C837275A9 from hkps server hkps.pool.sks-keyservers.net
gpg: /tmp/keyring/trustdb.gpg: trustdb created
gpg: key 634F4BD1E7AD5568: public key "Enrico Zini <enr...@enricozini.org>" imported
gpg: no ultimately trusted keys found
gpg: Total number processed: 1
gpg: imported: 1
gpg: Good signature from "Enrico Zini <enr...@enricozini.org>" [unknown]
gpg: aka "Enrico Zini <enr...@debian.org>" [unknown]
gpg: aka "Enrico Zini <enr...@truelite.it>" [unknown]
gpg: aka "Enrico Zini <enr...@enricozini.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: 1793 D6AB 7566 3E6B F104 953A 634F 4BD1 E7AD 5568
Subkey fingerprint: 1CC0 1267 007F ABE6 5846 6857 03D6 568C 8372 75A9

> I can switch to long key IDs, but I still get something that can match
> multiple keys:

64-bits key IDs are indeed vulnerable to collision attacks, but unlike
their 32-bits counterparts they are not known to be vulnerable to
preimage attacks. Thus long key ID impersonation is not known to be
possible at this point.

The OpenPGP Working Group is currently discussing an RFC 4880 revision
[1]. In particular, a new “Issuer Fingerprint” subpacket has been
proposed to deprecate the issuer subpacket and store full issuer
fingerprints rather than key IDs in OpenPGP signatures.

https://mailarchive.ietf.org/arch/msg/openpgp/LFtg4NzKEHIa8qTa4F0t7mr3JJQ

This would solve the problem of key impersonation if preimage attacks
become practical on 64-bits key IDs in the future, as
‘--keyserver-options=auto-key-retrieve’ would then be able to query the
issuing key based on its fingerprint not its (possibly colliding)
64-bits key ID. Moreover, I hope this would also make gpg able to
import two different keys colliding on their 64-bits key ID, which
currently fails (as keys are indexed by their 64-bits key ID ;-)

Cheers,
--
Guilhem.

[0] https://tools.ietf.org/html/rfc4880#section-5.2.3.5
[1] https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis
signature.asc

Holger Levsen

unread,
Jul 8, 2016, 12:30:04 PM7/8/16
to
On Fri, Jul 08, 2016 at 02:54:20PM +0200, Enrico Zini wrote:
> What if you received a message signed with key 9F6C6333?
>
> That is, what do you do (please list the practical steps) to validate a
> signature that is a few steps away from your key in the WoT?

trust in the real world depends on more things than a signed message. I
have traveled to other continents based on unsigned text messages,
because I could trust the contents (via other means than validating
signatures.)

so whether I would trust stuff signed by 0x44BB1BA79F6C6333 also
depends on the content of the message…


--
cheers,
Holger
signature.asc
0 new messages