# GNU Privacy Guard (GPG) The defacto implementation of the [[OpenPGP]] standard Links: [[PGP]] *GNU Privacy Guard (GnuPG or GPG) is a free-software replacement for Symantec's PGP cryptographic software suite. The software is compliant with RFC 4880, the IETF standards-track specification of OpenPGP. Modern versions of PGP are interoperable with GnuPG and other OpenPGP-compliant systems.[6]* - [Wikipedia page](https://www.wikiwand.com/en/GNU_Privacy_Guard) ## Resources - ([GitHub repo](https://github.com/drduh/YubiKey-Guide)) YubiKey Guide for GPG and SSH - ([YouTube video](https://www.youtube.com/watch?v=7LuMTyhFA-g)) How to set up Git commit signing with GPG and a YubiKey on macOS - ([GitHub help article](https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits)) Signing commits ## Install ### Install with [[Homebrew]] ```bash brew install gpg ``` ## Exporting a [[PGP]] key from [[Keybase]] This is done via the `keybase pgp export` command. Make sure keybase is installed (which installs the `keybase` CLI) and that it is running, and see help: ```bash $ keybase pgp export --help NAME: keybase pgp export - Export a PGP key from keybase USAGE: keybase pgp export [command options] DESCRIPTION: "keybase pgp export" exports public (and optionally private) PGP keys from Keybase, and into a file or to standard output. It doesn't access the GnuPG keychain at all. By default, when exporting private keys, you will be asked for passphrase to encrypt the exported keys. OPTIONS: -o, --outfile Specify an outfile (stdout by default). -s, --secret Export secret key. -q, --query Only export keys matching that query. --unencrypted When exporting private keys, do not protect with a passphrase. ``` ## Generate PGP key directly on [[YubiKey]] Based on [this Yubico support article](https://support.yubico.com/hc/en-us/articles/360013790259-Using-Your-YubiKey-with-OpenPGP) written on [[2020-05-12]] This is the safest option, but it means that if the Yubikey is lost, the private key is not recoverable. As long as you're not relying on your PGP key to access a critical service (e.g. just using it for git signing), this is probably an acceptable tradeoff. Consider using a second backup Yubikey to generate a second verified PGP key which can also be used to authenticate into the same services. ### Steps Based on the "Generating Your PGP Key directly on Your YubiKey" section of [this yubico support article](https://support.yubico.com/hc/en-us/articles/360013790259-Using-Your-YubiKey-with-OpenPGP). First, ensure `gpg` is installed. Insert YubiKey and show card status: ```bash $ gpg --card-status Reader ...........: Yubico YubiKey OTP FIDO CCID Application ID ...: <_> Application type .: OpenPGP Version ..........: 2.1 Manufacturer .....: Yubico Serial number ....: <_> Name of cardholder: [not set] Language prefs ...: [not set] Salutation .......: URL of public key : [not set] Login data .......: [not set] Signature PIN ....: not forced Key attributes ...: rsa2048 rsa2048 rsa2048 Max. PIN lengths .: 127 127 127 PIN retry counter : 3 0 3 Signature counter : 0 Signature key ....: [none] Encryption key....: [none] Authentication key: [none] General key info..: [none] ``` - Note the `Key attributes` field which specifies the key type you are currently using for (1) Signatures, (2) Encryption, and (3) Authentication - Notes on the PIN retry counters: - The counters show the number of remaining attemps for each available type of PIN. - [`3 0 3` is normal](https://forum.yubico.com/viewtopic5f07.html?p=8116) for YubiKey 4 (and presumably also for YubiKey 5/5C). - See also: [[YubiKey#PINs]] Open card edit menu: ```bash gpg --card-edit ``` Enter `admin` panel ```bash gpg/card> admin Admin commands are allowed ``` Optionally configure key attributes, e.g. you can change your RSA key size, or you can change the algorithm to ECC over [[Curve25519]] or [[NIST P-384]]. Note that: - ECC operations are only available for [[YubiKey]] firmware versions 5.2.3 or later - See section 6.4 of the [YubiKey 5 Series technical manual](https://docs.yubico.com/hardware/yubikey/yk-5/tech-manual/webdocs.pdf) - See [this YouTube comment](https://www.youtube.com/watch?v=7LuMTyhFA-g&lc=UgyAx3Kqvuc10rp_7B54AaABAg) lol - You can find the firmware version of your [[YubiKey]] using the [YubiKey manager](https://www.yubico.com/support/download/yubikey-manager/#h-downloads). - Note that YubiKey firmware is not upgradeable. ([source](https://support.yubico.com/hc/en-us/articles/360013708760-YubiKey-Firmware-Is-Not-Upgradeable#:~:text=Compatible%20devices&text=It%20is%20currently%20not%20possible,to%20be%20accessed%20or%20altered.)) - Yubikey 4 and up support 4096 RSA keys for PGP (source: [GitHub comment](https://github.com/Yubico/yubico-piv-tool/issues/58#issuecomment-473465290)) - When changing the pin, make sure to enter the *Admin PIN* (which defaults to `12345678`), not the *OpenPGP PIN* (which defaults to `123456`). - You can verify success with the `gpg/card> list` command, noting the `Key attributes` field. ```bash gpg/card> key-attr Changing card key attribute for: Signature key Please select what kind of key you want: (1) RSA (2) ECC Your selection? 1 What keysize do you want? (2048) 4096 The card will now be re-configured to generate a key of 4096 bits Changing card key attribute for: Encryption key Please select what kind of key you want: (1) RSA (2) ECC Your selection? 1 What keysize do you want? (2048) 4096 The card will now be re-configured to generate a key of 4096 bits Changing card key attribute for: Authentication key Please select what kind of key you want: (1) RSA (2) ECC Your selection? 1 What keysize do you want? (2048) 4096 The card will now be re-configured to generate a key of 4096 bits gpg/card> list Reader ...........: Yubico YubiKey OTP FIDO CCID Application ID ...: <_> Application type .: OpenPGP Version ..........: 2.1 Manufacturer .....: Yubico Serial number ....: <_> Name of cardholder: [not set] Language prefs ...: [not set] Salutation .......: URL of public key : [not set] Login data .......: [not set] Signature PIN ....: not forced Key attributes ...: rsa4096 rsa4096 rsa4096 Max. PIN lengths .: 127 127 127 PIN retry counter : 3 0 3 Signature counter : 0 Signature key ....: [none] Encryption key....: [none] Authentication key: [none] General key info..: [none] ``` Generate the key ```bash gpg/card> generate # The 'shim backup' is useless since it can't be used to recover the private key; just ignore Make off-card backup of encryption key? (Y/n) n # Specify expiration 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) 0 Key does not expire at all Is this correct? (y/N) y # Specify name, email, etc GnuPG needs to construct a user ID to identify your key. Real name: <name> Email address: <email> Comment: <optional, can put social @handle> You selected this USER-ID: "First Last (@handle) <[email protected]>" Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o # At this point, the key will generate. It takes a while, perhaps a minute. # The green light on the YubiKey flasehs while the key is being generated. gpg: directory '/Users/<user>/.gnupg/openpgp-revocs.d' created gpg: revocation certificate stored as '/Users/<user>/.gnupg/openpgp-revocs.d/<key>.rev' public and secret key created and signed. ``` - There's scarcely any information about the "shim backup" that mentions in the help article: "*This is a shim backup of the private key, not a full backup, and cannot be used to restore to a new YubiKey.*" - Some [reddit](https://www.reddit.com/r/yubikey/comments/ikbwp6/pgp_key_generationbackup_question/) [threads](https://www.reddit.com/r/yubikey/comments/r0b758/whats_the_shallow_copy_yubikey_5_nfc/) which show that everyone else is just as confused. tl;dr: it's probably useless. - Although the guide mentions that a (non-sensical) password must be supplied, I did not experience this when generating a key on my own [[YubiKey]] on [[2023-01-18]]. Follow up steps: see the [GitHub guide](https://github.com/drduh/YubiKey-Guide) for instructions on: - Using your YubiKey's OpenPGP function on multiple computers - More advanced usage of the YubiKey's OpenPGP application with GPG ### Setting up [[Git]] commit signing with [[GPG]] ```bash git config --global commit.gpgsign true git config --global user.signingkey 98F08E41D2257775 ``` List keys ```bash $ gpg --list-secret-keys --keyid-format=long /Users/fang/.gnupg/pubring.kbx ------------------------------ sec> rsa4096/98F08E41D2257775 2023-01-18 [SC] B53D291128DBF2F3697EFFBE98F08E41D2257775 Card serial no. = 0006 08713139 uid [ultimate] Max Fang (@maxfangx) <[email protected]> ssb> rsa4096/342B999AB1D955FA 2023-01-18 [A] ssb> rsa4096/86CF3F40D59AAD33 2023-01-18 [E] ``` Backup pubkey, e.g. put it in a [[GitHub]] gist ```bash $ gpg --armor --export 9600392115690F9 >> "pubkey.txt" $ cat pubkey.txt -----BEGIN PGP PUBLIC KEY BLOCK----- <lots of gibberish> -----END PGP PUBLIC KEY BLOCK----- ``` Notes: - List your keys with `gpg --list-secret-keys --keyid-format=long` - Export your key with `gpg --armor --export 9600392115690F9 >> "pubkey.txt"` - I didn't need the `export GPG_TTY=$(tty)` fix, but you can try it - In git config, `user.signingkey` *needs* to be set.