Autocrypt key rotation

Delta Chat uses Autocrypt for encryption.
Autocrypt standard specifies that OpenPGP key
conists of a signing EdDSA identity key
and encryption ECDH subkey.
Delta Chat allows to import OpenPGP keys
that do not conform to Autocrypt specification,
but let’s assume that primary key is capable of signing.

To rotate encryption key,
we need to remove all existing subkeys from OpenPGP key,
then generate and add a new encryption subkey.
To retain the ability to decrypt messages encrypted to old keys,
we need to store old encryption keys.
The simplest way is to clone the whole OpenPGP key
before rotation and store it in the keypairs table.
We can delete old keys after some time to provide Forward Secrecy.

To make key rotation work we need contacts
to accept the new Autocrypt key
as long as the primary key is not changed.
In many places we already compare primary key fingerprints
instead of the whole keys,
but changing the subkey has never been tested.
Most likely in the current state it will
not work as expected with “verified” keys
because they are stored separately from Autocrypt keys
and will not be updated when a new Autocrypt
key is received with known primary key
and updated encryption subkey.
Implmenting this key update logic
is the main step to make key rotation work.

Besides that, we need to test how Thunderbird reacts
to receiving an Autocrypt key with new encryption subkey.

All user devices have the same OpenPGP key,
so rotatitng the key
requires distributing new key to all devices.
The key has to be delivered to other devices
without using the old encryption key
to make it secure in case an attacker
can listen to the channel used for key distribution.

The simplest way would be
to use Autocrypt Setup Message for this.
Making key distribution explicit
prevents attacks where encryption key
is silently changed by an attacker
getting access to one of the devices device.

Distributing the key to other email clients
is also a problem.
Unfortunately, recent Thunderbird 115
does not support Autocrypt Setup Message.
In most cases reading chat messages
in Thunderbird is only useful for debugging,
so this problem is likely
not a concern for most users.

Another more complicated option
would be to introduce individual device keys.
Each device generates locally an OpenPGP device key
and distributes the public key to other devices
via synchronization messages.
Device secret keys should not be exported in a backup.
New devices should be explicitly approved by the user.
When some device wants to rotate the encryption key,
it can encrypt new key to all known device keys.
Devices can rotate their keys as frequently as wanted.

Third option is to use ratcheting,
i.e. calculating each next encryption key
by hashing previous encryption key.
Disadvantage is that this approach does not provide Post Compromise Security.
If old encryption key is leaked, new keys can be derived from it.
Ratcheting is only useful if device is configured to delete old messages
in which case attacker cannot use recent key to decrypt old messages stored on the server.
Post Compromise Security is useful not only in the case
when user keeps using previously compromised device,
but also when attacker gets access to old backup of the user device.

3 Likes

Related

Time-based ratcheting for OpenPGP (2021): Perfect forward secrecy in PGP with time-based ratcheting

Previous discussions on forward secrecy with OpenPGP:

There is a Double Ratchet implementation on top of OpenPGP at sequoia-pgp / openpgp-dr · GitLab with documentation at openpgp_dr - Rust

Forum topic on Off-the-Record chats:

1 Like

Loving this proposal @link2xt

For the record, have been collecting pointers on this topic at Email forward secrecy / double ratchet / off-the-records for autocrypt · Issue #444 · autocrypt/autocrypt · GitHub

1 Like

Removing subkeys is however not compatible with how OpenPGP implementations traditionally treat subkeys. OpenPGP certificates are treated as append-only, so some email client receiving all our Autocrypt headers over time can merge the certificates into a single huge certificate with all subkeys ever seen, both old and new.

Then once a large certificate is merged, it is not defined how subkeys used for encryption are selected. Some implementations will encrypt only to the most recent subkey and therefore can remove all old subkeys, but some implementations encrypt to all subkeys. There is a recent 2025-04-06 discussion on subkey selection at [openpgp] Encryption subkey selection with the proposal to introduce “rank” for subkeys.

Without introduction of new mechanisms such as key rank, we can use subkeys with expiration. The problem with expiration is that if you have not interacted with some contact for a while and the most recent subkey has expired, we will not be able to encrypt to this contact anymore. This is a common problem with expiration, also with TLS certificates. One solution would be to remember the last set of subkeys we used, and if at some point we cannot get a new set of usable subkeys from the certificate, use the last set we used.

Key rotation sounds generally more interesting than expiration to me. But even with key rotation,

  • without some simulation modeling there is a high risk talking about lots of technicalities without having an informed idea of outcomes.

  • there is an inherent dependency on how keys are distributed. If we have assisted flows for requesting updated keys it could be easier to rotate keys.

  • without analysis on user experience outcomes key rotation/expiry could become a bug/issue generator for years to come.

1 Like