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.