# Create a GPG Key (with SSH support!)
The following is based on [Creating newer ECC keys for GnuPG](https://www.gniibe.org/memo/software/gpg/keygen-25519.html) and [OpenPGP Best Practices](https://riseup.net/en/security/message-security/openpgp/best-practices). The idea here is to create a locked-down set of single-purpose keys that are rotated once per year (the 13 month expiration provides a little bit of wiggle-room).
## Create the initial key
```bash
gpg --expert --full-generate-key
```
- Choose "ECC (set your own capabilities)"
- Toggle the "Sign" capability *off* (`S`).
- Finish choosing capabilities (`Q`).
- Choose "Curve 25519".
- Expire in 13 months (`13m`).
- Enter your name.
- Enter the primary email address for the key.
- *Do not enter a comment.*
## Edit the key
```bash
gpg --expert --edit-key $KEYID
```
### Add UIDs
- Use `adduid`.
- Enter your name.
- Enter the primary email address for the key.
- *Do not enter a comment.*
### Add a signing subkey
- Use `addkey`.
- Choose "ECC (sign only)"
- Choose "Curve 25519".
- Expire in 13 months (`13m`).
### Add an authentication subkey
- Use `addkey`.
- Choose "ECC (set your own capabilities)"
- Toggle the "Sign" capability *off* (`S`).
- Toggle the "Authenticate" capability on (`A`).
- Finish choosing capabilities (`Q`).
- Choose "Curve 25519".
- Expire in 13 months (`13m`).
### Add an encryption subkey
- Use `addkey`.
- Choose "ECC (encrypt only)"
- Choose "Curve 25519".
- Expire in 13 months (`13m`).
### Finish up
Be sure to save the key before exiting.
## Remove the primary key for safe keeping
```bash
# Export keys
#
gpg --armor --export-secret-key $KEYID > $KEYID.asc
gpg --export-secret-subkeys $KEYID > subkeys.gpg
# Delete secret keys (BOTH primary and subkeys)
#
gpg --delete-secret-keys $KEYID
# Re-import secret subkeys
#
gpg --import subkeys.gpg
# Optionally verify that eveything worked...
#
gpg --list-keys
gpg --list-secret-keys
# Cleanup
#
rm subkeys.gpg
```
Once this is done, `$KEYID.asc` can be stored "offline" on a secure (encrypted!) drive, etc. Note that this key will need to be re-imported to generate new subkeys, add UIDs, extend expiration dates, or create updated revocation certificates.
## Export the authentication subkey to SSH
- Run `gpg --list-secret-keys --with-keygrip`.
- [Copy keygrips of the authentication subkeys (`A`) you want to use in SSH to `~/.gnupg/sshcontrol`.](https://opensource.com/article/19/4/gpg-subkeys-ssh)
- [Generate the SSH public key using `gpg --export-ssh-key $KEYID > ~/.ssh/id_${KEYID}.pub`.](https://serverfault.com/questions/906871/force-the-use-of-a-gpg-key-as-an-ssh-key-for-a-given-server/964317#964317) This key can then be referenced using the IdentityFile directive in `~/.ssh/config` or inserted into a host's `~/.ssh/authorized_keys` file.