16 KiB
OpenPGP Setup
Master key
$ gpg --gen-random --armor 0 24
wgwCNncu2POgMJwX/zSJUrBpRvgD95LT
Important: Save this credential in a permanent, secure place as it will be needed to issue new sub-keys after expiration, and to provision additional YubiKeys.
Generate a new key with GPG, selecting (8) RSA (set your own capabilities), Certify capability only and 4096 bit key size.
Important: Do not set the master key to expire.
$ gpg --expert --full-generate-key
gpg (GnuPG) 2.2.19; Copyright (C) 2019 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
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)
(13) Existing key
(14) Existing key from card
Your selection? 8
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? e
Possible actions for a RSA key: Sign Certify Encrypt Authenticate
Current allowed actions: Sign Certify
(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
(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? (3072) 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)
Key does not expire at all
Is this correct? (y/N) y
GnuPG needs to construct a user ID to identify your key.
Real name: Maurice Preuß
Email address: hello@envoyr.com
Comment: Testing
You are using the 'utf-8' character set.
You selected this USER-ID:
"Maurice Preuß (Testing) <hello@envoyr.com>"
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
gpg: /root/.gnupg/trustdb.gpg: trustdb created
gpg: key 2FB2BECD1F7F3DD2 marked as ultimately trusted
gpg: directory '/root/.gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/root/.gnupg/openpgp-revocs.d/8941D3AA5A48FDA1C9B9655D2FB2BECD1F7F3DD2.rev'
public and secret key created and signed.
pub rsa4096 2022-04-24 [C]
8941D3AA5A48FDA1C9B9655D2FB2BECD1F7F3DD2
uid Maurice Preuß (Testing) <hello@envoyr.com>
Export the key ID as a variable (KEYID) for use later:
$ export KEYID=8941D3AA5A48FDA1C9B9655D2FB2BECD1F7F3DD2
Sign with existing key
Optional: If you already have a PGP key, you may want to sign the new key with the old one to prove that the new key is controlled by you.
Export your existing key to move it to the working keyring:
$ gpg --export-secret-keys --armor --output /tmp/new.sec
Then sign the new key:
$ gpg --default-key $OLDKEY --sign-key $KEYID
Sub keys
Edit the master key to add sub-keys:
$ gpg --expert --edit-key $KEYID
gpg (GnuPG) 2.2.19; Copyright (C) 2019 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Secret key is available.
gpg: checking the trustdb
gpg: marginals needed: 3 completes needed: 1 trust model: pgp
gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u
sec rsa4096/2FB2BECD1F7F3DD2
created: 2022-04-24 expires: never usage: C
trust: ultimate validity: ultimate
[ultimate] (1). Maurice Preuß (Testing) <hello@envoyr.com>
Use 4096-bit RSA keys.
Use a 1 year expiration for sub-keys - they can be renewed using the offline master key. See rotating keys.
Signing
Create a signing key by selecting addkey then (4) RSA (sign only):
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
(14) Existing key from card
Your selection? 4
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (3072) 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) 1y
Key expires at Mon 24 Apr 2023 04:42:12 PM UTC
Is this correct? (y/N) y
Really create? (y/N) y
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
sec rsa4096/2FB2BECD1F7F3DD2
created: 2022-04-24 expires: never usage: C
trust: ultimate validity: ultimate
ssb rsa4096/AFE0490C5483E698
created: 2022-04-24 expires: 2023-04-24 usage: S
[ultimate] (1). Maurice Preuß (Testing) <hello@envoyr.com>
Encryption
Next, create an encryption key by selecting (6) RSA (encrypt only):
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
(14) Existing key from card
Your selection? 6
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (3072) 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) 1y
Key expires at Mon 24 Apr 2023 04:43:19 PM UTC
Is this correct? (y/N) y
Really create? (y/N) y
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
sec rsa4096/2FB2BECD1F7F3DD2
created: 2022-04-24 expires: never usage: C
trust: ultimate validity: ultimate
ssb rsa4096/AFE0490C5483E698
created: 2022-04-24 expires: 2023-04-24 usage: S
ssb rsa4096/E6CF1F243E533507
created: 2022-04-24 expires: 2023-04-24 usage: E
[ultimate] (1). Maurice Preuß (Testing) <hello@envoyr.com>
Authentication
Finally, create an authentication key.
GPG doesn't provide an authenticate-only key type, so select (8) RSA (set your own capabilities) and toggle the required capabilities until the only allowed action is Authenticate:
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
(14) Existing key from card
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? E
Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions:
(S) Toggle the sign capability
(E) Toggle the encrypt capability
(A) Toggle the authenticate capability
(Q) Finished
Your selection? A
Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions: Authenticate
(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? (3072) 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) 1y
Key expires at Mon 24 Apr 2023 04:44:50 PM UTC
Is this correct? (y/N) y
Really create? (y/N) y
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
sec rsa4096/2FB2BECD1F7F3DD2
created: 2022-04-24 expires: never usage: C
trust: ultimate validity: ultimate
ssb rsa4096/AFE0490C5483E698
created: 2022-04-24 expires: 2023-04-24 usage: S
ssb rsa4096/E6CF1F243E533507
created: 2022-04-24 expires: 2023-04-24 usage: E
ssb rsa4096/2209B814758777B0
created: 2022-04-24 expires: 2023-04-24 usage: A
[ultimate] (1). Maurice Preuß (Testing) <hello@envoyr.com>
Finish by saving the keys.
gpg> save
Verify
List the generated secret keys and verify the output:
$ gpg -K
/root/.gnupg/pubring.kbx
------------------------
sec rsa4096 2022-04-24 [C]
8941D3AA5A48FDA1C9B9655D2FB2BECD1F7F3DD2
uid [ultimate] Maurice Preuß (Testing) <hello@envoyr.com>
ssb rsa4096 2022-04-24 [S] [expires: 2023-04-24]
ssb rsa4096 2022-04-24 [E] [expires: 2023-04-24]
ssb rsa4096 2022-04-24 [A] [expires: 2023-04-24]
Export keys and ownertrust
The master key and sub-keys will be encrypted with your passphrase when exported.
Save a copy of your keys:
$ gpg --armor --export $KEYID > public.key
$ gpg --armor --export-secret-keys $KEYID > master.asc
$ gpg --armor --export-secret-subkeys $KEYID > subkeys.asc
$ gpg --export-ownertrust > ownertrust.txt
Import keys and ownertrust
$ gpg --import public.key
$ gpg --import master.asc
$ gpg --import subkeys.asc
$ gpg --import-ownertrust ownertrust.txt
Ultimately trust the imported key
This is so that I can encrypt data using my public key
$ gpg --edit-key 1E0B5331219BEA88
gpg> trust
Your decision? 5 (Ultimate trust)
Information: If I don't trust the public key then I see the following message when trying to encrypt something with it:
gpg: <key-id>: There is no assurance this key belongs to the named user
Revocation certificate
Although we will backup and store the master key in a safe place, it is best practice to never rule out the possibility of losing it or having the backup fail. Without the master key, it will be impossible to renew or rotate subkeys or generate a revocation certificate, the PGP identity will be useless.
Even worse, we cannot advertise this fact in any way to those that are using our keys. It is reasonable to assume this will occur at some point and the only remaining way to deprecate orphaned keys is a revocation certificate.
To create the revocation certificate:
$ gpg --output revoke.asc --gen-revoke $KEYID
sec rsa4096/2FB2BECD1F7F3DD2 2022-04-24 Maurice Preuß (Testing) <hello@envoyr.com>
Create a revocation certificate for this key? (y/N) y
Please select the reason for the revocation:
0 = No reason specified
1 = Key has been compromised
2 = Key is superseded
3 = Key is no longer used
Q = Cancel
(Probably you want to select 1 here)
Your decision? 1
Enter an optional description; end it with an empty line:
>
Reason for revocation: Key has been compromised
(No description given)
Is this okay? (y/N) y
ASCII armored output forced.
Revocation certificate created.
Please move it to a medium which you can hide away; if Mallory gets
access to this certificate he can use it to make your key unusable.
It is smart to print this certificate and store it away, just in case
your media become unreadable. But have some caution: The print system of
your machine might store the data and make it available to others!
The revoke.asc certificate file should be stored (or printed) in a (secondary) place that allows retrieval in case the main backup fails.
Create new USB
Write it with random data to prepare for encryption (1x random & 1x null):
$ sudo shred -vfzn1 /dev/sdc
Erase and create a new partition table:
$ sudo fdisk /dev/sdc
Welcome to fdisk (util-linux 2.33.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Device does not contain a recognized partition table.
Created a new DOS disklabel with disk identifier 0x3c1ad14a.
Command (m for help): g
Created a new GPT disklabel (GUID: 4E7495FD-85A3-3E48-97FC-2DD8D41516C3).
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
Create a new partition with a 25 Megabyte size:
$ sudo fdisk /dev/sdc
Welcome to fdisk (util-linux 2.33.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Command (m for help): n
Partition type
p primary (0 primary, 0 extended, 4 free)
e extended (container for logical partitions)
Select (default p): p
Partition number (1-4, default 1):
First sector (2048-31116287, default 2048):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-31116287, default 31116287): +25M
Created a new partition 1 of type 'Linux' and of size 25 MiB.
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
Use LUKS to encrypt the new partition:
$ sudo cryptsetup luksFormat /dev/sdcp1
WARNING!
========
This will overwrite data on /dev/sdcp1 irrevocably.
Are you sure? (Type uppercase yes): YES
Enter passphrase for /dev/sdcp1:
Verify passphrase:
Mount the partition:
$ sudo cryptsetup luksOpen /dev/sdcp1 secret
Enter passphrase for /dev/sdcp1:
Create a filesystem:
$ sudo mkfs.ext2 /dev/mapper/secret -L gpg
Creating filesystem with 9216 1k blocks and 2304 inodes
Superblock backups stored on blocks:
8193
Allocating group tables: done
Writing inode tables: done
Writing superblocks and filesystem accounting information: done
Mount the filesystem and copy the temporary directory with the keyring:
$ sudo mkdir /mnt/encrypted-storage
$ sudo mount /dev/mapper/secret /mnt/encrypted-storage
$ sudo cp -avi $GNUPGHOME /mnt/encrypted-storage/
Unmount, close and disconnect the encrypted volume:
$ sudo umount /mnt/encrypted-storage/
$ sudo cryptsetup luksClose secret