Skip to content

Instantly share code, notes, and snippets.

@cjyar
Last active March 19, 2024 17:13
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cjyar/f7c677b613365297bcc690a0360c9327 to your computer and use it in GitHub Desktop.
Save cjyar/f7c677b613365297bcc690a0360c9327 to your computer and use it in GitHub Desktop.
Secure OpenPGP Configuration

Discussion

You can have many different levels of security with PGP. For lots of people, keeping your master key on your computer is good enough, and it's better than no PGP at all. But this guide is my max-security PGP setup. Here are the threats and mitigations that I'm concerned with:

  • Quantum cracking: It's likely that someday people will be able to crack RSA and DSA keys using quantum computers. ECC keys are likely also crackable, but can be faster, shorter, and possibly more secure. There's some controversy about which type of ECC keys to use; I settled on Curve 25519.
  • Key reuse: It's a bad idea to reuse your encryption key for signing. (It's safe with current algorithms, but it might be unsafe with future algorithms; and it compartmentalizes risk.) PGP has four kinds of keys: Encryption, Signing, Authentication, and Certification. You should have a dedicated key for each purpose.
    • Encryption: Other people use this to send you encrypted messages that only you can read.
    • Signing: You use this to sign a message, proving that it was really sent by you. You can also sign Git commits or compiled programs to certify them.
    • Authentication: You use this to authenticate yourself via things like ssh.
    • Certification: A special form of signing where you use your master key to certify a subkey. You publish the public master key, the public subkey, and the certification all together when you push your "key" to a keyserver.
  • Keyboard sniffing: If somebody pwns your box, they can read your PGP key in its encrypted form; and they can read the corresponding password when you type it. To prevent this, use a PGP smartcard like the YubiKey. Generate the private key on the YubiKey; the YubiKey is designed so that private key can never be retrieved. Note that PGP smartcards like the YubiKey can only do RSA keys, though. (The PGP smartcard standard doesn't support other key types yet, but they're working on it.)
  • Master key compromise: If somebody steals your master key, and you know about it, the best you can do is revoke the key and start from scratch with new keys that you have to set up distribute to all your contacts. If your key is stolen and you don't know it, you have bigger problems; master keys are typically very long lived. So it's best to have shorter-lived operational keys -- subkeys -- that you use on a daily basis.
  • Offline cracking: If somebody steals the encrypted form of your private key, they might be able to crack it even without your passphrase. (Or you might have an easy-to-guess passphrase.) So for your valuable master key, the private key should be stored offline, where it won't be as accessible to malware.
  • Key size: For RSA keys, you shouldn't use anything smaller than 2048. There's only a moderate improvement in security by going to 4096, though; it may not be worth it. The YubiKey was designed to prevent side channel attacks against keys of 2048 bits; they claim their algorithms extend that protection to 4096 bit keys, but you may choose not to believe that.

Putting it all together, I recommend using an ECC key as your master key. This key is generated on an offline computer such as Debian's Clean Room Live Environment. Then you insert your YubiKey and have it generate your three operational keys, all signed by your master. Now you carry your YubiKey with you for daily PGP operations; the YubiKey makes it very easy to use good crypto. If the YubiKey is lost or stolen -- or when its keys expire -- you boot up your clean room and use it to sign new YubiKey keys.

Side Note on RSA Paranoia

NIST says that RSA-2048 will be good until the year 2030. NIST also recommends the Government stop using RSA immediately in favor of ECC. Some people don't trust that NIST has good intentions, and they see this as evidence that NIST wants us to use supposedly weak RSA crypto while they use stronger ECC.

Now imagine you work for the Government, and you follow recommendations from NIST and the NSA. The NSA doesn't care about the encrypted messages you're going to send tomorrow; they care about what you sent yesterday. Assume that every message you send is wiretapped, in its encrypted form, and archived by your adversaries. If your key is ever compromised, your adversaries will decrypt anything they can from those archives. So if NIST says to stop using RSA ten years before it's crackable, that means they think today's Top Secret transmissions could be damaging ten years from now, if they were revealed.

Recipe

  1. Configure YubiKey.
    1. Insert your YubiKey into your offline computer.
    2. gpg --card-edit
    3. admin
    4. passwd to set your PIN and admin password for the PGP keys on this YubiKey.
    5. key-attr to set the desired key length.
    6. q to exit GPG.
  2. Generate the master key.
    1. Boot your offline environment.
    2. gpg --full-generate-key --expert
    3. ECC (set your own capabilities)
    4. Toggle Sign so the key is Certify only.
    5. Curve 25519
    6. An expiration that you can bump later if you don't lose your key: 1.5-2 years.
  3. Create an operational key directly on the YubiKey. (Once each for Sign, Encrypt, Authenticate.)
    1. addcardkey
    2. A one year lifespan is probably correct.
  4. Publish your key.
    1. gpg --list-keys to get your key ID.
    2. gpg --export -a $keyID
    3. Move that to an online computer (your workstation), and then:
    4. gpg --import $keyFile
    5. Insert your YubiKey.
    6. gpg --card-status to associate the YubiKey.
    7. gpg --send-keys $keyId

SSH

For bonus points, you can use that PGP identity as your ssh identity.

  1. Get your ssh key, which is derived from your PGP key.
    1. On your workstation, insert your YubiKey.
    2. gpg --edit-key --expert $masterKeyID to get your key IDs for all your subkeys. Then use q to exit.
    3. gpg --export-ssh-key $subKeyID for a subkey marked with A. This is one very long line of text which is your ssh identity.
  2. Configure your workstation.
    • Follow one of the guides published by Yubico.
    • Mac:
      1. brew install gnupg pinentry-mac
      2. Edit ${HOME}/.gnupg/gpg-agent.conf:
        pinentry-program /usr/local/bin/pinentry-mac
        enable-ssh-support
        
      3. Add to ${HOME}/.bash_profile:
        export GPG_TTY=$(tty)
        export "SSH_AUTH_SOCK=${HOME}/.gnupg/S.gpg-agent.ssh"
        
      4. Add to ${HOME}/.gnupg/scademon.conf:
        disable-ccid
        
  3. Authorize that ssh key.
    1. Log in to the server that you want to be able to ssh to.
    2. Add that long line of text to your $HOME/.ssh/authorized_keys file.
    3. Consider disabling password-based login in /etc/ssh/sshd_config:
      ChallengeResponseAuthentication no
      PasswordAuthentication no
      UsePAM no
      

Please let me know about any errors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment