Skip to content Skip to footer

How to Use Your GPG Key as an SSH Key (Step-by-Step)

how to use gpg key

One key to sign them all, one key to bind them, one key to log you in and—if stolen—quickly un-find them.
In an age of relentless credential leaks and “rotate your secrets now!” alerts, developers want fewer keys to love and fewer chances to slip. Reusing a well-protected GPG key for SSH logins is a smart, publicly documented trick—but it still isn’t mainstream. This guide shows you how to do it safely, why it beats juggling separate private keys, and which pitfalls to avoid. Strap in: by the time you finish, you’ll have a single hardware-backed key unlocking e-mail encryption and every server you own.

The 2025 Case for Key Consolidation

Back in 2015, most engineers kept a handful of private keys on disk, protected by a half-remembered passphrase. That was fine—until the DevOps explosion. Today you might authenticate to:

  • A Git host (GitHub, GitLab, Bitbucket)

  • A half-dozen cloud VMs

  • Kubernetes jump boxes

  • CI/CD runners

  • A home-lab Raspberry Pi cluster

Every destination wants a distinct public key, auditors want rotation logs, and security teams want hardware tokens. The result is “key sprawl”: ten keys, ten passphrases, ten places to fat-finger.

GPG-SSH unification kills the sprawl in three ways:

  1. Single root of trust. Your master OpenPGP key already signs e-mails, packages, or Git commits. Extending its authority to SSH makes audits trivial.

  2. Hardware enforcement. Modern YubiKeys, Nitrokeys and SoloKeys speak both OpenPGP and FIDO2. One tap unlocks e-mail and servers; no files ever leave the chip.

  3. Revocation simplicity. Lose your token? Revoke one sub-key, issue a replacement, update authorized_keys with a script. Done.

In short: fewer secrets, stronger guarantees, lower cognitive load. Now let’s build it.

What Is GPG?

Ever wondered what is GPG and why security pros rave about it? Short for GNU Privacy Guard, GPG is the free, open-source successor to PGP, empowering you to encrypt, sign, and even authenticate everything from email to server logins. Picture a digital padlock with two halves: one public key you share freely and one private key you guard like gold. The result? Breaches become far less scary, and compliance audits feel almost painless.

Quick Primer—GPG, Sub-Keys, and SSH

Term

One-sentence translation

GPG (GNU Privacy Guard)

Free implementation of the OpenPGP encryption-and-signing standard.

SSH (Secure Shell)

Encrypted protocol for remote login, tunnelling, and Git over the network.

Asymmetric key pair

Public key (the lock) + private key (the key) = encrypted mailboxes and password-less logins.

Master key

The top-level OpenPGP key that certifies all sub-keys; you guard it like gold.

Sub-key

A child key that inherits trust from the master but can be rotated or revoked independently.

Why all the fuss about sub-keys? Because they’re compartmentalisation in cryptographic form. You can tuck the master offline on an air-gapped laptop or a print-out in a vault, then create three sub-keys:

  • Encryption (for messages/files)

  • Signing (for e-mail, Git tags)

  • Authentication (for SSH)

If the authentication sub-key ever leaks, you revoke only that child, issue a new one, and keep on signing releases with the untouched S-sub-key. Elegant, auditable, battle-tested.

Environment-Ready Checklist

  1. Operating system

    • Linux (Debian/Ubuntu/Fedora/Arch)

    • macOS (Intel/Apple Silicon)

    • Windows 11 with WSL 2 (recommended) or native Gpg4win

Packages

# Debian/Ubuntu

sudo apt install gnupg2 openssh-client pinentry-gtk2 scdaemon

# macOS

brew install gnupg pinentry-mac yubikey-personalization

  1.  
  2. Hardware token (optional but ideal)

    • YubiKey 5C/5Ci/5NFC

    • Nitrokey Start/3A, SoloKey v2

Why hardware? Keys inside silicon cannot be copied. A rogue root shell may still tamper with your OS, but it cannot steal metal.

Generate—or Extend—Your OpenPGP Key

Scenario A: fresh start

 

gpg –full-generate-key

 

Pick:

  • (9) ECC and ECC → curve ed25519 (fast, quantum-resistant-ish)

  • Usage: Sign, Encrypt, Certify

  • Expiry: 3 years (you’ll renew sub-keys yearly)

Scenario B: upgrade an existing key

 

gpg –list-secret-keys –keyid-format LONG

gpg –edit-key ABCD1234EFGH5678

 

Inside the interactive prompt:

sql

CopyEdit

gpg> addkey

Please select what kind of key:

(1) RSA (sign only)

(8) ECC (sign only)

(9) ECC and ECC

 

Choose ECC then flag usage as Authenticate. Set an expiry (1 year recommended). Finish with save.

When you exit, gpg -K –with-subkey-fingerprint should list a new line marked A—your shiny SSH sub-key.

Turning GPG Agent into an SSH Agent

OpenSSH ships with its own agent (ssh-agent) that watches ~/.ssh/id_*. GPG has a rival: gpg-agent, which can masquerade as an SSH agent if you ask politely.

Edit ~/.gnupg/gpg-agent.conf

python
CopyEdit
enable-ssh-support

pinentry-program /usr/bin/pinentry-gtk-2   # or pinentry-mac

default-cache-ttl 900       # 15 min

max-cache-ttl 7200          # 2 h

  1.  

Restart the agent

gpgconf –kill gpg-agent

eval “$(gpg-agent –daemon –enable-ssh-support)”

  1.  That eval exports SSH_AUTH_SOCK pointing at GPG’s socket. Add it to your .bashrc or .zshrc.

Confirm

ssh-add -l

4096 ED25519 SHA256:abcd… cardno:FFFE12345678 (GPG: authentication)

  1.  

If you see “agent has no identities,” the sub-key isn’t cached yet—use ssh-add -L after touching the token.

Export the Sub-Key in OpenSSH Format

 

gpg –export-ssh-key ABCD1234EFGH5678

 

You get one long ssh-ed25519 AAAAC3Nz… [email protected] line. Copy it verbatim to the remote server:

bash

CopyEdit

ssh user@server ‘mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys’

 

Finish with:

chmod 700 ~/.ssh

chmod 600 ~/.ssh/authorized_keys

 

Pro tip: store the public line in your password manager labeled “GPG-SSH public” so you can paste it into any new VM in seconds.

First Login & Deep-Dive Debugging

Run:

ssh -o LogLevel=DEBUG3 user@server

 

Watch for these lines:

Offering public key: cardno:FFFE12345678

sign_and_send_pubkey: signing using cardno:FFFE12345678

Authentication succeeded (publickey).

 

Stalls?

  • agent refused operation → token not unlocked. Run gpg –card-status; if it asks for PIN, enter it once—then try SSH again.

  • no such identity → environment changed. Confirm echo $SSH_AUTH_SOCK shows your home dir’s .gnupg/S.gpg-agent.ssh, not /tmp/ssh-XXXX/agent.pid.

  • PubkeyAlgorithms mismatch → the server only allows FIPS curves. Generate a cv25519 (X25519) or RSA 4096 auth sub-key.

Hardening with Hardware—Life on a YubiKey

A plastic dongle the size of a fingernail adds friction, but also super-powers:

Feature

Benefit

Command

Touch-to-sign

Human presence check defeats malware & Supply-Chain 21 attacks

ykman openpgp set-touch aut on

PIN & PUK

Brute-force throttle; 3 wrong PINs, then PUK needed

ykman openpgp set-pin-retries 3 10

PIV + OpenPGP

Same stick stores FIDO2, TOTP, ED25519, and PIV certs

ykman piv info

Story from the field: A fintech startup in Tel Aviv switched 40 engineers from file-based SSH keys to YubiKey-backed sub-keys. In month one they halved help-desk tickets about “I lost my laptop” because a stolen laptop no longer meant “nuke every production key.” Audit time dropped from five days to two hours: security just grepped YubiKey serials in authorized_keys against HR’s roster.

Automating Sub-Key Rotation

Security auditors love the phrase “crypto agility.” Here’s a Bash/Ansible duo that rotates an auth sub-key every quarter:

#!/bin/bash

MASTER=$1  # 16-char keyid

# 1. Mint new auth sub-key (expires in 1 year)

echo -e “addkey\n8\nA\n1y\nsave\n” | gpg –command-fd 0 –edit-key $MASTER

NEW=$(gpg –list-keys –with-colons $MASTER | grep ‘^sub:’ | tail -1 | cut -d: -f5)

# 2. Export in SSH format

gpg –export-ssh-key $MASTER | tail -n 1 > /tmp/$NEW.pub

 

Then an Ansible playbook:

yaml

CopyEdit

– hosts: all

  tasks:

    – name: Push new GPG-SSH key

      authorized_key:

        user: “{{ ansible_user }}”

        key: “{{ lookup(‘file’, ‘/tmp/’ + newkey + ‘.pub’) }}”

 

Finally, remove the previous public key with authorized_key state=absent once all hosts confirm new logins.

Git over GPG-Backed SSH

  1. Add key to GitHub
    Settings → SSH & GPG Keys → New SSH Key → Paste.

Sign commits with the same token

git config –global user.signingkey ABCD1234EFGH5678

git commit -S -m “One token to push and sign”

  1.  
  2. Single tap, dual effect. Push (git push origin main) triggers one tap for SSH auth; the signed commit piggybacks on GPG’s cached PIN— seamless developer flow.

Insider tip: GitHub recognizes the YubiKey’s sign only sub-key for commit signatures and the auth sub-key for SSH. You never expose the encryption sub-key on a server, keeping secret messages strictly P2P.

Advanced Use: Double-Wrapping Sensitive Files

For classified reports or customer databases in transit:

bash

CopyEdit

# Encrypt file for recipient

gpg –recipient 0xBEEFCAFE –encrypt payroll.csv

# Copy over SSH tunnel

scp payroll.csv.gpg finance@vault:/incoming/

 

Why bother if SSH is already encrypted? Layered defense. If the SSH endpoint is ever compromised (rogue root shell, Heartbleed-style memory dump), the captured file is still unreadable without the recipient’s private key.

Pair this with an MFT platform: configure a pre-transfer GPG encryption hook and a post-transfer decryption hook on the destination. Auditors tick off “data at rest encrypted” and “data in motion encrypted” in one glance.

Troubleshooting Cheat-Sheet

Error

Root Cause

Quick Fix

sign_and_send_pubkey: agent refused operation

Sub-key on hardware but touch not confirmed

Touch the token; ensure LED flashes.

gpg: decryption failed: No secret key

Wrong smartcard inserted

gpg –card-status to list card serials; swap token.

Bad ownership or modes for directory /home/user/.gnupg

Agent refuses world-readable dirs

chmod 700 ~/.gnupg && chmod 600 ~/.gnupg/*

gpg-agent[1234]: starting in ssh mode failed: Address already in use

Competing ssh-agent still running

pkill ssh-agent && eval “$(gpg-agent –daemon –enable-ssh-support)”

Keep this table near your coffee mug; 90 % of support questions boil down to these four lines.

Security Checklist (Copy-Pastable)

 

[ ] Master OpenPGP key offline, encrypted, with paper backup

[ ] Auth sub-key on hardware token; no private bits on disk

[ ] PIN changed from factory default; touch-to-sign enforced

[ ] gpg-agent socket exported; ssh-agent disabled

[ ] default-cache-ttl ≤ 900 seconds

[ ] Sub-key rotation script scheduled quarterly

[ ] Revocation certificate printed + stored off-site

[ ] CI/CD runners mount token in read-only USB mode

[ ] Production servers accept ONLY ed25519-sk or rsa-sha2-512 keys

 

Stick this in your team wiki and revisit it every sprint retro.

Putting It All Together

By now you’ve:

  1. Generated—or upgraded—a GPG key with an authentication sub-key.

  2. Convinced gpg-agent to moonlight as an SSH agent.

  3. Logged into a server with a single hardware tap.

  4. Automated rotation, Git pushes, and double-wrapped file transfers.

That’s defense in depth sealed inside a five-gram USB stick. No extra daemons, no proprietary software, no vendor lock-in—just battle-hardened open standards.

The payoff? Peace of mind. Lose a laptop? Disable one sub-key. Ship code from a coffee shop? A shoulder-surfer can’t replicate your fingerprint. Hungry auditors? Hand them a CSV of YubiKey serials and sub-key fingerprints—job done.

Welcome! Let's start the journey

AI Personal Consultant

Chat: AI Chat is not available - token for access to the API for text generation is not specified