Have you upgraded your keys to Ed25519?

3 minute read Published: 2021-03-05

RSA keys with 1024 and 2048 bits are considered obsolete and insecure, the recommended minimal length is 3072, preferably 4096 bit. Currently I have some 4096 bits keys but they're slow when encrypting and decrypting. The algo Ed25519 is available since years and has now wide support around, so there's no reason to not use it anymore. Let's have a quick overview of the advantages.

Warning to the casual bypasser: ensure to have GnuPG >= v2.1.7.

Note: the following will use the Ed25519 algo for GPG keys, but the general point applies also to SSH keys. Stop using RSA basically.

§ Smaller

$ ssh-keygen -t rsa -b 4096 -C "RSA 4096 bit Keys" -N "" -f test.rsa
$ ssh-keygen -t ed25519 -C "ed25519" -N "" -f test.ed25519
$ ls -la test.*
-rw------- 1 user user  399 Mar  5 01:23 test.ed25519
-rw-r--r-- 1 user user   89 Mar  5 01:23 test.ed25519.pub
-rw------- 1 user user 3381 Mar  5 01:22 test.rsa
-rw-r--r-- 1 user user  743 Mar  5 01:22 test.rsa.pub

§ Faster

Generating a RSA 4096 key with one subkey (params: gen-params-rsa4096):

$ time gpg --batch --generate-key gen-params-rsa4096

real    0m12.429s
user    0m0.022s
sys 0m0.008s

against the same with Ed25519 key (params: gen-params-ed25519):

$ time gpg --batch --generate-key gen-params-ed25519

real    0m1.029s
user    0m0.006s
sys 0m0.005s

Encryption and decryption with RSA 4096 on a single file does not look significantly slower, but enough to be noticed when working on a lot of files (example when I open a mail webclient and many emails are decrypted).

§ Bonus: scripting a Ed25519 key+subkey generation

I went through the GPG documentation and various other answers around so hopefully I don't have to do it again.

Note: only one subkey can be handled, see Subkey-Type.

Run the previous command:

$ gpg --batch --generate-key gen-params-ed25519

Retrieve the key fingerprint:

$ gpg --list-keys
/tmp/tmp.PVi2JP7r0I/pubring.kbx
-------------------------------
pub   ed25519 2021-03-05 [C]
      1F5E3B7C28CD82184DF382B05D797E94AEF1B672
uid           [ultimate] Joe Tester (with stupid passphrase) <ed25519@foo.bar>

1F5E3B7C28CD82184DF382B05D797E94AEF1B672 is your fingerprint. The master key can have no expiry and be the ultimate key you use to generate subkeys.

Create the signing subkey

gpg --batch --passphrase '' \
    --quick-add-key 1F5E3B7C28CD82184DF382B05D797E94AEF1B672 \
    ed25519 sign 1y

Create the authorization subkey

gpg --batch --passphrase '' \
    --quick-add-key 1F5E3B7C28CD82184DF382B05D797E94AEF1B672 \
    ed25519 auth 1y

Create the encryption subkey

gpg --batch --passphrase '' \
    --quick-add-key 1F5E3B7C28CD82184DF382B05D797E94AEF1B672 \
    cv25519 encrypt 1y

Note: for the encryption key you must specify cv25519 instead of ed25519 as protocol. Ed25519 is a digital signature algorithm only (that uses Curve25519) so it can't be used for an encryption key.

For more in-depth info, please visit the definitive guide of drduh to creating GPG keys.

§ Bonus (2): quick create a GPG key for signing git commits

I use specific GPG key only for signing commits, so I can generate a key that is only able to sign:

gpg --quick-generate-key user@codeforge.tld ed25519 sign never