Key-pair Setup (*January 5, 2025*) Begin by installing the below tool for your OS: - Windows: GPG4Win - Mac: GPGTools - Linux: GnuPG.org This note uses Ubuntu and GnuPG. Before key creation add the following to your `gpg.conf` file: ```conf no-emit-version no-comments export-options export-minimal keyid-format 0xlong with-fingerprint list-options show-uid-validity verify-options show-uid-validity personal-cipher-preferences AES256 personal-digest-preferences SHA512 default-preference-list SHA512 SHA384 SHA256 RIPEMD160 AES256 TWOFISH BLOWFISH ZLIB BZIP2 ZIP Uncompressed cipher-algo AES256 digest-algo SHA512 cert-digest-algo SHA512 compress-algo ZLIB disable-cipher-algo 3DES weak-digest SHA1 s2k-cipher-algo AES256 s2k-digest-algo SHA512 s2k-mode 3 s2k-count 65011712 ``` We'll utilize OpenPGP's subkey feature to create a more secure and flexible key setup. Subkeys offer specialized functions (Signing, Encrypting, Authentication). This approach allows for revoking individual subkeys without compromising the master key if necessary. Let's create the master key for my user account 'char'. This key will certify all others. ```shell char@rack2:~$ gpg --expert --full-gen-key Please select what kind of key you want: (1) RSA and RSA (default) (2) DSA and Elgamal (3) DSA (sign only) (4) RSA (sign only) (7) DSA (set your own capabilities) (8) RSA (set your own capabilities) (9) ECC and ECC (10) ECC (sign only) (11) ECC (set your own capabilities) Your selection? 8 Then you have to select the attributes of this key. Only the capability Certify. Possible actions for a RSA key: Sign Certify Encrypt Authenticate Current allowed actions: Sign Certify Encrypt (S) Toggle the sign capability (E) Toggle the encrypt capability (A) Toggle the authenticate capability (Q) Finished Your selection? s Possible actions for a RSA key: Sign Certify Encrypt Authenticate Current allowed actions: Certify Encrypt (S) Toggle the sign capability (E) Toggle the encrypt capability (A) Toggle the authenticate capability (Q) Finished Your selection? e Possible actions for a RSA key: Sign Certify Encrypt Authenticate Current allowed actions: Certify (S) Toggle the sign capability (E) Toggle the encrypt capability (A) Toggle the authenticate capability (Q) Finished Your selection? q ``` Follow the prompts opting for the 4096-bit key size for higher security. For the lifetime of the key, it's always recommended to put one. If this key is lost and it has been sent to a key server it will remain there forever valid. I tend to use a duration of 2-3 years. ```shell RSA keys may be between 1024 and 4096 bits long. What keysize do you want? (2048) 4096 Requested keysize is 4096 bits Please specify how long the key should be valid. 0 = key does not expire <n> = key expires in n days <n>w = key expires in n weeks <n>m = key expires in n months <n>y = key expires in n years Key is valid for? (0) 2y Key does not expire at all Is this correct? (y/N) y Let's add details about char's identity: GnuPG needs to construct a user ID to identify your key. Real name: Char Blog Email address: char.blog Comment: You selected this USER-ID: "Char Blog <char.blog>" Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o ``` A window will appear and it will ask you to fill in a passphrase to protect the secret keys. Choose one that's long enough that you can memorize easily but is complex enough. With the master key in-place we'll add subkeys for: Authentication (A), Signing (S), and Encryption (E). List your available keys: ```shell char@rack2:~$ gpg --list-keys /home/char/.gnupg/pubring.gpg -------------------------------- pub rsa4096/12345678 2024-10-15 [C] [expires: 2026-10-15] uid [ultimate] Char Blog <[email protected]> ``` Edit to add a new subkey: ```shell char@rack2:~$ gpg --expert --edit-key 12345678 ``` Follow the process to add a new encryption key: ```shell gpg> addkey Please select what kind of key you want: (3) DSA (sign only) (4) RSA (sign only) (5) Elgamal (encrypt only) (6) RSA (encrypt only) (7) DSA (set your own capabilities) (8) RSA (set your own capabilities) (10) ECC (sign only) (11) ECC (set your own capabilities) (12) ECC (encrypt only) (13) Existing key Your selection? 8 Possible actions for a RSA key: Sign Encrypt Authenticate Current allowed actions: Sign Encrypt (S) Toggle the sign capability (E) Toggle the encrypt capability (A) Toggle the authenticate capability (Q) Finished Your selection? s Possible actions for a RSA key: Sign Encrypt Authenticate Current allowed actions: Encrypt (S) Toggle the sign capability (E) Toggle the encrypt capability (A) Toggle the authenticate capability (Q) Finished Your selection? q RSA keys may be between 1024 and 4096 bits long. What keysize do you want? (2048) 4096 Requested keysize is 4096 bits Please specify how long the key should be valid. 0 = key does not expire <n> = key expires in n days <n>w = key expires in n weeks <n>m = key expires in n months <n>y = key expires in n years Key is valid for? (0) 2y Is this correct? (y/N) y Really create? (y/N) y ``` Repeat these steps for Signing and Authentication keys, it'll end up looking something like this: ```shell sec rsa4096/12345678 created: 2024-10-15 expires: 2026-10-15 usage: C trust: ultimate validity: ultimate ssb rsa4096/12345678 created: 2024-10-15 expires: 2026-10-15 usage: E ssb rsa4096/12345678 created: 2024-10-15 expires: 2026-10-15 usage: A ssb rsa4096/12345678 created: 2024-10-15 expires: 2026-10-15 usage: S [ultimate] (1). Char Blog <[email protected]> gpg> save gpg> quit ``` It's important to create a revocation certificate in the event that your master key is compromised: ```shell char@rack2:~$ gpg --output 12345678.rev --gen-revoke 12345678 ``` Make sure you keep this somewhere safe, ideally on some sort of offline storage (make sure to backup). Now let's save all keys, delete all private keys, then import only the private keys for each subkey so that the master key is set as a stub: ```shell char@rack2:~$ gpg --export --armor 12345678 > 12345678.pub.asc char@rack2:~$ gpg --export-secret-keys --armor 12345678 > 12345678.priv.asc char@rack2:~$ gpg --export-secret-subkeys --armor 12345678 > 12345678.sub_priv.asc char@rack2:~$ gpg --delete-secret-key 12345678 char@rack2:~$ gpg --import 12345678.sub_priv.asc char@rack2:~$ gpg --list-secret-keys /home/char/.gnupg/secring.gpg sec# rsa4096/12345678 2024-10-15 [C] [expires: 2026-10-15] uid [ultimate] Char Blog <[email protected]> ssb rsa4096/12345678 2024-10-15 [E] [expires: 2026-10-15] ssb rsa4096/12345678 2024-10-15 [S] [expires: 2026-10-15] ssb rsa4096/12345678 2024-10-15 [A] [expires: 2026-10-15] ``` You can now uses these subkeys to authenticate with SSH, sign your GitHub commits, and encrypt your emails without ever compromising your master key. P.S. Make sure to put a calendar entry in for your key expiry dates.