The Case for Short OpenPGP Key Validity Periods
After I moved to a new OpenPGP key (see key transition statement) I have received comments about the short life length of my new key. When I created the key (see my GnuPG setup) I set it to expire after 100 days. Some people assumed that I would have to create a new key then, and therefore wondered what value there is to sign a key that will expire in two months. It doesn’t work like that, and below I will explain how OpenPGP key expiration works; how to extend the expiration time of your key; and argue why having a relatively short validity period can be a good thing.
The OpenPGP message format has a sub-packet called the Key Expiration Time, quoting the RFC:
5.2.3.6. Key Expiration Time
(4-octet time field)
The validity period of the key. This is the number of seconds after
the key creation time that the key expires. If this is not present
or has a value of zero, the key never expires. This is found only on
a self-signature.
You can print the sub-packets in your OpenPGP key with gpg --list-packets
. See below an output for my key, and notice the “created 1403464490″ (which is Unix time for 2014-06-22 21:14:50) and the “subpkt 9 len 4 (key expires after 100d0h0m)” which adds up to an expiration on 2014-09-26. Don’t confuse the creation time of the key (“created 1403464321″) with when the signature was created (“created 1403464490″).
jas@latte:~$ gpg --export 54265e8c | gpg --list-packets |head -20
:public key packet:
version 4, algo 1, created 1403464321, expires 0
pkey[0]: [3744 bits]
pkey[1]: [17 bits]
:user ID packet: "Simon Josefsson "
:signature packet: algo 1, keyid 0664A76954265E8C
version 4, created 1403464490, md5len 0, sigclass 0x13
digest algo 10, begin of digest be 8e
hashed subpkt 27 len 1 (key flags: 03)
hashed subpkt 9 len 4 (key expires after 100d0h0m)
hashed subpkt 11 len 7 (pref-sym-algos: 9 8 7 13 12 11 10)
hashed subpkt 21 len 4 (pref-hash-algos: 10 9 8 11)
hashed subpkt 30 len 1 (features: 01)
hashed subpkt 23 len 1 (key server preferences: 80)
hashed subpkt 2 len 4 (sig created 2014-06-22)
hashed subpkt 25 len 1 (primary user ID)
subpkt 16 len 8 (issuer key ID 0664A76954265E8C)
data: [3743 bits]
:signature packet: algo 1, keyid EDA21E94B565716F
version 4, created 1403466403, md5len 0, sigclass 0x10
jas@latte:~$
So the key will simply stop being valid after that time? No. It is possible to update the key expiration time value, re-sign the key, and distribute the key to people you communicate with directly or indirectly to OpenPGP keyservers. Since that date is a couple of weeks away, now felt like the perfect opportunity to go through the exercise of taking out my offline master key and boot from a Debian LiveCD and extend its expiry time. See my earlier writeup for LiveCD and USB stick conventions.
user@debian:~$ export GNUPGHOME=/media/FA21-AE97/gnupghome
user@debian:~$ gpg --edit-key 54265e8c
gpg (GnuPG) 1.4.12; Copyright (C) 2012 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Secret key is available.
pub 3744R/54265E8C created: 2014-06-22 expires: 2014-09-30 usage: SC
trust: ultimate validity: ultimate
sub 2048R/32F8119D created: 2014-06-22 expires: 2014-09-30 usage: S
sub 2048R/78ECD86B created: 2014-06-22 expires: 2014-09-30 usage: E
sub 2048R/36BA8F9B created: 2014-06-22 expires: 2014-09-30 usage: A
[ultimate] (1). Simon Josefsson
[ultimate] (2) Simon Josefsson
gpg> expire
Changing expiration time for the primary key.
Please specify how long the key should be valid.
0 = key does not expire
= key expires in n days
w = key expires in n weeks
m = key expires in n months
y = key expires in n years
Key is valid for? (0) 150
Key expires at Fri 23 Jan 2015 02:47:48 PM UTC
Is this correct? (y/N) y
You need a passphrase to unlock the secret key for
user: "Simon Josefsson "
3744-bit RSA key, ID 54265E8C, created 2014-06-22
pub 3744R/54265E8C created: 2014-06-22 expires: 2015-01-23 usage: SC
trust: ultimate validity: ultimate
sub 2048R/32F8119D created: 2014-06-22 expires: 2014-09-30 usage: S
sub 2048R/78ECD86B created: 2014-06-22 expires: 2014-09-30 usage: E
sub 2048R/36BA8F9B created: 2014-06-22 expires: 2014-09-30 usage: A
[ultimate] (1). Simon Josefsson
[ultimate] (2) Simon Josefsson
gpg> key 1
pub 3744R/54265E8C created: 2014-06-22 expires: 2015-01-23 usage: SC
trust: ultimate validity: ultimate
sub* 2048R/32F8119D created: 2014-06-22 expires: 2014-09-30 usage: S
sub 2048R/78ECD86B created: 2014-06-22 expires: 2014-09-30 usage: E
sub 2048R/36BA8F9B created: 2014-06-22 expires: 2014-09-30 usage: A
[ultimate] (1). Simon Josefsson
[ultimate] (2) Simon Josefsson
gpg> expire
Changing expiration time for a subkey.
Please specify how long the key should be valid.
0 = key does not expire
= key expires in n days
w = key expires in n weeks
m = key expires in n months
y = key expires in n years
Key is valid for? (0) 150
Key expires at Fri 23 Jan 2015 02:48:05 PM UTC
Is this correct? (y/N) y
You need a passphrase to unlock the secret key for
user: "Simon Josefsson "
3744-bit RSA key, ID 54265E8C, created 2014-06-22
pub 3744R/54265E8C created: 2014-06-22 expires: 2015-01-23 usage: SC
trust: ultimate validity: ultimate
sub* 2048R/32F8119D created: 2014-06-22 expires: 2015-01-23 usage: S
sub 2048R/78ECD86B created: 2014-06-22 expires: 2014-09-30 usage: E
sub 2048R/36BA8F9B created: 2014-06-22 expires: 2014-09-30 usage: A
[ultimate] (1). Simon Josefsson
[ultimate] (2) Simon Josefsson
gpg> key 2
pub 3744R/54265E8C created: 2014-06-22 expires: 2015-01-23 usage: SC
trust: ultimate validity: ultimate
sub* 2048R/32F8119D created: 2014-06-22 expires: 2015-01-23 usage: S
sub* 2048R/78ECD86B created: 2014-06-22 expires: 2014-09-30 usage: E
sub 2048R/36BA8F9B created: 2014-06-22 expires: 2014-09-30 usage: A
[ultimate] (1). Simon Josefsson
[ultimate] (2) Simon Josefsson
gpg> key 1
pub 3744R/54265E8C created: 2014-06-22 expires: 2015-01-23 usage: SC
trust: ultimate validity: ultimate
sub 2048R/32F8119D created: 2014-06-22 expires: 2015-01-23 usage: S
sub* 2048R/78ECD86B created: 2014-06-22 expires: 2014-09-30 usage: E
sub 2048R/36BA8F9B created: 2014-06-22 expires: 2014-09-30 usage: A
[ultimate] (1). Simon Josefsson
[ultimate] (2) Simon Josefsson
gpg> expire
Changing expiration time for a subkey.
Please specify how long the key should be valid.
0 = key does not expire
= key expires in n days
w = key expires in n weeks
m = key expires in n months
y = key expires in n years
Key is valid for? (0) 150
Key expires at Fri 23 Jan 2015 02:48:14 PM UTC
Is this correct? (y/N) y
You need a passphrase to unlock the secret key for
user: "Simon Josefsson "
3744-bit RSA key, ID 54265E8C, created 2014-06-22
pub 3744R/54265E8C created: 2014-06-22 expires: 2015-01-23 usage: SC
trust: ultimate validity: ultimate
sub 2048R/32F8119D created: 2014-06-22 expires: 2015-01-23 usage: S
sub* 2048R/78ECD86B created: 2014-06-22 expires: 2015-01-23 usage: E
sub 2048R/36BA8F9B created: 2014-06-22 expires: 2014-09-30 usage: A
[ultimate] (1). Simon Josefsson
[ultimate] (2) Simon Josefsson
gpg> key 3
pub 3744R/54265E8C created: 2014-06-22 expires: 2015-01-23 usage: SC
trust: ultimate validity: ultimate
sub 2048R/32F8119D created: 2014-06-22 expires: 2015-01-23 usage: S
sub* 2048R/78ECD86B created: 2014-06-22 expires: 2015-01-23 usage: E
sub* 2048R/36BA8F9B created: 2014-06-22 expires: 2014-09-30 usage: A
[ultimate] (1). Simon Josefsson
[ultimate] (2) Simon Josefsson
gpg> key 2
pub 3744R/54265E8C created: 2014-06-22 expires: 2015-01-23 usage: SC
trust: ultimate validity: ultimate
sub 2048R/32F8119D created: 2014-06-22 expires: 2015-01-23 usage: S
sub 2048R/78ECD86B created: 2014-06-22 expires: 2015-01-23 usage: E
sub* 2048R/36BA8F9B created: 2014-06-22 expires: 2014-09-30 usage: A
[ultimate] (1). Simon Josefsson
[ultimate] (2) Simon Josefsson
gpg> expire
Changing expiration time for a subkey.
Please specify how long the key should be valid.
0 = key does not expire
= key expires in n days
w = key expires in n weeks
m = key expires in n months
y = key expires in n years
Key is valid for? (0) 150
Key expires at Fri 23 Jan 2015 02:48:23 PM UTC
Is this correct? (y/N) y
You need a passphrase to unlock the secret key for
user: "Simon Josefsson "
3744-bit RSA key, ID 54265E8C, created 2014-06-22
pub 3744R/54265E8C created: 2014-06-22 expires: 2015-01-23 usage: SC
trust: ultimate validity: ultimate
sub 2048R/32F8119D created: 2014-06-22 expires: 2015-01-23 usage: S
sub 2048R/78ECD86B created: 2014-06-22 expires: 2015-01-23 usage: E
sub* 2048R/36BA8F9B created: 2014-06-22 expires: 2015-01-23 usage: A
[ultimate] (1). Simon Josefsson
[ultimate] (2) Simon Josefsson
gpg> save
user@debian:~$ gpg -a --export 54265e8c > /media/KINGSTON/updated-key.txt
user@debian:~$
I remove the “transport” USB stick from the “offline” computer, and back on my laptop I can inspect the new updated key. Let’s use the same command as before. The key creation time is the same (“created 1403464321″), of course, but the signature packet has a new time (“created 1409064478″) since it was signed now. Notice “created 1409064478″ and “subpkt 9 len 4 (key expires after 214d19h35m)”. The expiration time is computed based on when the key was generated, not when the signature packet was generated. You may want to double-check the pref-sym-algos, pref-hash-algos and other sub-packets so that you don’t accidentally change anything else. (Btw, re-signing your key is also how you would modify those preferences over time.)
jas@latte:~$ cat /media/KINGSTON/updated-key.txt |gpg --list-packets | head -20
:public key packet:
version 4, algo 1, created 1403464321, expires 0
pkey[0]: [3744 bits]
pkey[1]: [17 bits]
:user ID packet: "Simon Josefsson "
:signature packet: algo 1, keyid 0664A76954265E8C
version 4, created 1409064478, md5len 0, sigclass 0x13
digest algo 10, begin of digest 5c b2
hashed subpkt 27 len 1 (key flags: 03)
hashed subpkt 11 len 7 (pref-sym-algos: 9 8 7 13 12 11 10)
hashed subpkt 21 len 4 (pref-hash-algos: 10 9 8 11)
hashed subpkt 30 len 1 (features: 01)
hashed subpkt 23 len 1 (key server preferences: 80)
hashed subpkt 25 len 1 (primary user ID)
hashed subpkt 2 len 4 (sig created 2014-08-26)
hashed subpkt 9 len 4 (key expires after 214d19h35m)
subpkt 16 len 8 (issuer key ID 0664A76954265E8C)
data: [3744 bits]
:user ID packet: "Simon Josefsson "
:signature packet: algo 1, keyid 0664A76954265E8C
jas@latte:~$
Being happy with the new key, I import it and send it to key servers out there.
jas@latte:~$ gpg --import /media/KINGSTON/updated-key.txt
gpg: key 54265E8C: "Simon Josefsson " 5 new signatures
gpg: Total number processed: 1
gpg: new signatures: 5
jas@latte:~$ gpg --send-keys 54265e8c
gpg: sending key 54265E8C to hkp server keys.gnupg.net
jas@latte:~$ gpg --keyserver keyring.debian.org --send-keys 54265e8c
gpg: sending key 54265E8C to hkp server keyring.debian.org
jas@latte:~$
Finally: why go through this hassle, rather than set the key to expire in 50 years? Some reasons for this are:
- I don’t trust myselt to keep track of a private key (or revocation cert) for 50 years.
- I want people to notice my revocation certificate as quickly as possible.
- I want people to notice other changes to my key (e.g., cipher preferences) as quickly as possible.
Let’s look into the first reason a bit more. What would happen if I lose both the master key and the revocation cert, for a key that’s valid 50 years? I would start from scratch and create a new key that I upload to keyservers. Then there would be two keys out there that are valid and identify me, and both will have a set of signatures on it. None of them will be revoked. If I happen to lose the new key again, there will be three valid keys out there with signatures on it. You may argue that this shouldn’t be a problem, and that nobody should use any other key than the latest one I want to be used, but that’s a technical argument — and at this point we have moved into usability, and that’s a trickier area. Having users select which out of a couple of apparently all valid keys that exist for me is simply not going to work well.
The second is more subtle, but considerably more important. If people retrieve my key from keyservers today, and it expires in 50 years, there will be no need to refresh it from key servers. If for some reason I have to publish my revocation certificate, there will be people that won’t see it. If instead I set a short validity period, people will have to refresh my key once in a while, and will then either get an updated expiration time, or will get the revocation certificate. This amounts to a CRL/OCSP-like model.
The third is similar to the second, but deserves to be mentioned on its own. Because the cipher preferences are expressed (and signed) in my key, and that ciphers come and go, I would expect that I will modify those during the life-time of my long-term key. If I have a long validity period of my key, people would not refresh it from key servers, and would encrypt messages to me with ciphers I may no longer want to be used.
The downside of having a short validity period is that I have to do slightly more work to get out the offline master key once in a while (which I have to once in a while anyway because I’m signing other peoples keys) and that others need to refresh my key from the key servers. Can anyone identify other disadvantages? Also, having to explain why I’m using a short validity period used to be a downside, but with this writeup posted that won’t be the case any more.
Syndicated 2014-08-26 18:11:27 from Simon Josefsson's blog