# 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.