# OpenPGP Workshop [important reference](img/iceberg.png) --- ## What is OpenPGP * OpenPGP is an open standard for encrypting and decrypting data, as well as creating and managing digital signatures. * It is based on the PGP (Pretty Good Privacy) protocol, which was originally developed by Phil Zimmermann in the 1990s. * Uses asymmetric / public key cryptography --- ## Implementations * GPG * Gnu Privacy Guard * Best known and most widely used * Great starting point * There are lots of other implementations of OpenPGP: * https://www.openpgp.org/software/developer/ --- ## How Does It Work? --- ## Encrypt / Decrypt ![Encryption vs Decryption diagram](img/encrypt-decrypt.png) --- ## Sign / Verify ![Signing vs Verifying diagram](img/sign-verify.png) --- ## Diffie Helman Key Exchange ![Diffie Helman Key Exchange diagram](img/diffie-helman.png) --- ## OpenPGP Anatomy * Many components but key ones are: * Public Key * Private Key --- ## Let's Try It! * Most OS come with GPG pre-installed (not Windows!) * `gpg --version` * `man gpg` * **THESE FOLLOWING KEYS WILL NOT BE SECURE, DO NOT USE THEM FOR ANYTHING OTHER THAN THIS EXERCISE!** * Generate keypair: `gpg --expert --full-gen-key` * 1, 4096, Enter (3072), Enter (0), y, "Test Key", , Enter (""), O, "password1" * Use a unique email otherwise you will have issues with the exercise that follows * During generation, **mash input devices for added entropy** --- ## Test Your GPG Key * `gpg --list-keys` * `echo "super secret text" > test.txt && cat test.txt` * `gpg --encrypt --recipient test.txt` * `gpg -er && cat text.txt.gpg`: notice it's a binary * You can use `--armor/-a` to encode it as ASCII so you can send the encrypted data as text * `gpg --armor -er test.txt && cat test.txt.asc` * `rm test.txt && ls`: remove original file * `gpg --decrypt test.txt.gpg && cat test.txt && rm test.txt` * `gpg --decrypt test.txt.asc && cat test.txt && rm text.txt` --- ## Sharing Your Public Key 🔑 * `gpg --list-keys` * `gpg --export --armor > .asc` * `gpg --import .asc` * Task: pair up and exchange your keys, encrypt data to each other, then decrypt the message so you can tell your partner the contents of the message * Tip: you may encrypt the data to multiple people --- ## What's Happening Behind the Scenes * GPG generates a symmetric key (AES) and uses that to encrypt the bulk of the data * RSA/ECC is used only to encrypt the symmetric key * The encrypted data packet contains metadata about which public keys were encrypted to * This can be hidden using `--hidden-recipient/-R` * Inspect packets using `gpg --list-packets ` --- ## Verifying Signatures 📝 * Go to: https://www.qubes-os.org/downloads/ * Download: * Qubes-R*.iso * Cryptographic hash values * Detached PGP signature * Qubes release signing key * They have a guide that's worth reading: https://www.qubes-os.org/security/verifying-signatures/ * Task: verify the signatures for the software are valid --- ## Solution * `gpg --import qubes-release-*`: import qubes signing key * `gpg --verify *.DIGESTS`: verify signature * `sha256sum -c Qubes-<...>.iso.DIGESTS`: verify hashes match --- ## Secure Key Management 🔒 * You should assume your computer is compromised * How do we protect the GPG private key? * Never expose them to an untrusted environment --- ## Basic: On-board generation: * YubiKey offers generating keys inside of the YubiKey * Cryptographic attestation keys were never exposed available: https://developers.yubico.com/PGP/Attestation.html * CON: can't back up the keys * PRO: simple setup --- ## Advanced - cold / virtualization * Can use `gpg` / `sq` / `keyfork` * [Hashbang GPG Guide](https://book.hashbang.sh/docs/security/key-management/gnupg/): helpful guide for GPG - good resource for beginners who want to do the advanced setup * [openpgp-card-tools](https://codeberg.org/openpgp-card/openpgp-card-tools): great for loading keys onto smart cards * Can use a variety of smart cards: NitroKey3, SoloKey, Yubikey * NitroKey and SoloKey are fully open which is great for verifiability - may requires flashing firmware * [openpgp-card-tools](https://codeberg.org/openpgp-card/openpgp-card-tools) is helpful for loading the card * Airgapped system (preferred) * Virtual machine on a hypervisor via hardware virtualization (ok for some threat models) --- ## Backup Trick 🧙 * Generate long lived keys * Load them onto smart card * Take plaintext key data and put it in a dir * Encrypt the dir to your public key * Delete keys so that only ones that remain are on smart cards (recommended to have at least 2 or 3, for redundancy) * Smart cards have a "brick" after x attempts feature --- ## SSH Usage * OpenPGP keys can be used for SSH as well 🪄: * `gpg --export-ssh-key ` * Set up shell to use smart card for ssh: ``` # always use smart card for ssh unset SSH_AGENT_PID if [ "${gnupg_SSH_AUTH_SOCK_by:-0}" -ne $$ ]; then export SSH_AUTH_SOCK="$(gpgconf --list-dirs agent-ssh-socket)" fi ``` --- ## Git Usage * You can sign commits using OpenPGP / GPG ```~/.bashrc GPG_TTY=$(tty) export GPG_TTY ``` ```~/.gitconfig [user] email = name = signingKey = [commit] gpgSign = true [merge] gpgSign = true [gpg] program = gpg ``` --- ## Further Studies * [pass](https://www.passwordstore.org/): Unix based `gpg` password manager * [OpenPGP for application developers](https://openpgp.dev/book/): Deep dive on OpenPGP * [Sequoia](https://sequoia-pgp.org/): alternate OpenPGP implementation in rust * [openpgp-card](https://codeberg.org/openpgp-card) * [openpgp-card-tools](https://codeberg.org/openpgp-card/openpgp-card-tools) * [ssh-agent](https://codeberg.org/openpgp-card/ssh-agent)