presentations/openpgp-workshop/index.md

5.9 KiB

OpenPGP Workshop

important reference


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


How Does It Work?


Encrypt / Decrypt

Encryption vs Decryption diagram


Sign / Verify

Signing vs Verifying diagram


Diffie Helman Key Exchange

Diffie Helman Key Exchange diagram


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", <your_email>, 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 <email/ID> test.txt
  • gpg -er <email/ID> <filename> && cat test.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 <email/ID> test.txt && cat test.txt.asc
  • rm test.txt && ls
  • gpg --decrypt test.txt.gpg > test.txt
  • gpg --decrypt test.txt.asc > test.txt

Sharing Your Public Key 🔑

  • gpg --list-keys

  • gpg --export --armor <email/ID> > <name>.asc

  • gpg --import <name>.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 <file.asc/file.gpg>


Verifying Signatures 📝


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:


Advanced - cold / virtualization

  • Can use gpg / sq / keyfork

  • Hashbang GPG Guide: helpful guide for GPG - good resource for beginners who want to do the advanced setup

  • 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 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 <email/keyID>
  • 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

    GPG_TTY=$(tty)
    export GPG_TTY
    
    [user]
        email = <email>
        name = <name>
        signingKey = <key_id>
    [commit]
        gpgSign = true
    [merge]
        gpgSign = true
    [gpg]
        program = gpg
    

Further Studies