What is a YubiKey?

A YubiKey is a small hardware device used as a second factor of authentication. It works similarly to one-time codes sent by SMS or email - but much more securely. To authenticate, the YubiKey must be physically inserted into your computer or connected via NFC. This makes it nearly impossible for remote attackers to compromise your credentials.

Getting a YubiKey

The best place to buy a YubiKey is directly from Yubico . You can also buy them from trusted retailers, but always verify the device is genuine using Yubico’s verification page .

Tip

It’s recommended to have at least two YubiKeys as a backup in case you lose or damage the primary device.


Initial Setup

First, install YubiKey Manager and change the default PINs and management keys. Here is a good guide about that: Changing the default management key and PIN


Other Prerequisites

Since, we want to use the YubiKey for SSH authentication and Git signing, install these tools:

brew install gnupg ykman pinentry-mac

GPG Interface

The GPG (OpenPGP) interface on the YubiKey uses two separate PINs:

  • Admin PIN: required when loading GPG keys to the YubiKey. Default: 12345678
  • User PIN: used when signing, encrypting, or authenticating. Default: 123456

You can change them using:

ykman openpgp access change-admin-pin
ykman openpgp access change-pin

By default, the YubiKey automatically approves signing and encryption requests when inserted. For extra security, I recommend enabling touch confirmation:

ykman openpgp keys set-touch aut off
ykman openpgp keys set-touch sig on
ykman openpgp keys set-touch enc on

Create GPG Keys and Upload to YubiKey

Create a temporary directory which will be cleared on reboot and set it as the GnuPG directory:

export GNUPGHOME=$(mktemp -d -t $(date +%Y.%m.%d)-XXXX)
cd $GNUPGHOME

Generate a new GPG key:

gpg --expert --full-generate-key

Choose:

9 - ECC sign & encrypt
Curve 25519
Does not expire
Choose a strong but memorable password

The password you set here is your GPG Key Password.

Export the Key ID

List your keys and note the Key ID:

gpg --list-secret-keys --keyid-format=long

Example output:

sec>  ed25519/E965C2667A7373F1 2025-11-05 [SC]
      F510240484630D8494F7EF10E965C2667A7373F1
uid                 [ultimate] Your Name (Comment) <[email protected]>
ssb>  cv25519/C00CCD4A3EACEA9E 2025-11-05 [E]

The Key ID is E965C2667A7373F1.

export KEY_ID="E965C2667A7373F1"

Adding Additional Identities

If you want to use the same key for multiple email addresses:

gpg --expert --edit-key $KEY_ID
> adduid

Follow the prompts and type save when done.


Changing Expiration and Creating Subkeys

Let’s change expiration for encryption key:

gpg --expert --edit-key $KEY_ID
> key 1
> expire

Choose:

Key is valid for? (0) 2y
Is this correct? (y/N) y

save

Create signing subkey:

gpg --expert --edit-key $KEY_ID
> addkey

Choose:

(11) ECC (set your own capabilities)
(Q) Finished
(1) Curve 25519 _default_
2y

Create authentication subkey:

gpg --expert --edit-key $KEY_ID
> addkey

Choose:

(11) ECC (set your own capabilities)
(S) Toggle the sign capability
(A) Toggle the authenticate capability
(Q) Finished
(1) Curve 25519 _default_
2y

save and quit.


Exporting Keys

The primary key is responsible for issuing Subkeys for encryption, signature and authentication operations. The primary key should be kept offline at all times and only accessed from a dedicated and secure environment to issue or revoke Subkeys.

gpg --armor --export-secret-keys $KEY_ID > primary.key
gpg --armor --export-secret-subkeys $KEY_ID > sub.key
gpg --armor --export $KEY_ID > public.key
echo $KEY_ID > key_id

Create an encrypted/password protected archive and store it in a secure location.


Copy public key to a key registry

Go to https://keys.openpgp.org and upload your public key and verify the email.

This service we will be using later to import the public key.


Uploading Keys to YubiKey

gpg --expert --edit-key $KEY_ID
> key 1
> keytocard

Choose (2) Encryption key and answer the password/PIN prompts as before. Next:

> key 1
> key 2
> keytocard

Choose (1) Signature key, it’ll prompt for the GPG Password, then it’ll ask for the GPG Admin PIN. Next:

> key 2
> key 3
> keytocard

Choose (3) Authentication key and passwords/PINs again. save and quit.

Tip

If you want to configure additional yubikey, you need to restore GPG keys from the backup, import them and repeat the process of uploading to the new yubikey.


Git Signing Configuration

Configure Git to sign commits automatically:

git config --global user.signingkey $KEY_ID
git config --global commit.gpgsign true

Export your public key and add it to GitHub or GitLab:

gpg --armor --export $KEY_ID | pbcopy

And paste the value into your GitHub/Gitlab settings.


SSH Configuration

Export your public key in SSH format:

gpg --export-ssh-key $KEY_ID

Add it to your remote services (GitHub, GitLab, Bitbucket, etc.).

Configure GPG Agent

Create or edit ~/.gnupg/gpg-agent.conf:

enable-ssh-support
pinentry-program /opt/homebrew/bin/pinentry-mac

Restart the agent:

gpg-connect-agent updatestartuptty /bye > /dev/null

And add this to ~/.ssh/config:

Host *
    IdentityAgent ~/.gnupg/S.gpg-agent.ssh

Switching Between Keys

If you use multiple YubiKeys, GPG needs to refresh the active key. Add this helper function to your .zshrc or .bashrc:

function switchyubi() {
  rm -r ~/.gnupg/private-keys-v1.d
  gpgconf --kill gpg-agent
  gpg --card-status
}

Run switchyubi after plugging in your YubiKey to reload the correct key.


Testing

Open a new terminal/session and run

export KEY_ID=965C2667A7373F1 # Replace with your KEY_ID
gpg --keyserver hkps://keys.openpgp.org --recv-keys $KEY_ID
switchyubi
> gpg --list-keys --keyid-format=long
[keyboxd]
---------
pub   ed25519/E965C2667A7373F1 2025-11-05 [SC]
      F510240484630D8494F7EF10E965C2667A7373F1
uid                 [ultimate] Your Name (Comment) <[email protected]>
ssb>  cv25519/C00CCD4A3EACEA9E 2025-11-05 [E] [expires: 2027-11-05]
sub>  ed25519/7A3EACEA9EDF123D 2025-11-05 [S] [expires: 2027-11-05]
sub>  ed25519/ACEA9E2342DDE33C 2025-11-05 [A] [expires: 2027-11-05]

Conclusion

Using a YubiKey for SSH and Git signing adds a strong security layer without sacrificing convenience. It is a great step toward securing your workflow and protecting your digital identity.


Sources