Published: Nov 10, 2022

Debian - Setup GPG/SSH for Github

Introduction

SSH keys are used to securely access remote servers, execute commands or pull/push to github repositories.

GPG keys are usually used to securely transmit information between two parties. This includes verifying that the origin of a message is genuine. GPG keys can also be used to sign git commits.

Always keep your private keys on your device, don’t upload them anywhere and use strong passwords to protect them in case the keyfile is stolen.

Software

I use KeePassXC to store SSH keys and other passwords in an encrypted file which is then shared between devices using a peer-to-peer file synchronization software like syncthing or resilio-sync.

If you prefer to use a GUI for your SSH and GPG keys try seahorse for linux/mac or gpg4win for windows.

Generate key pairs

SSH

To generate an SSH key pair use ssh-keygen (part of openssh-client).

> ssh-keygen -t ed25519 -C "your_email@example.com"

Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/user/.ssh/id_ed25519): 
Created directory '/home/user/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/user/.ssh/id_ed25519
Your public key has been saved in /home/user/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:mO5QYPuoCMZ+Xx0u6RjuHS1l9s+1guTp57rCfoICVDM your_email@example.com
The key's randomart image is:
+--[ED25519 256]--+
|                 |
|     E           |
|    + o          |
|   o o o         |
|  . . + S=       |
|.  . =  O o.     |
|.o  +.o*o+o.o  . |
|+. o.+*.++ =oo. .|
|..o o=oo..=+=+.. |
+----[SHA256]-----+

GPG

For the GPG key pair make sure you have gpg package installed. Then run following command and follow the instructions on screen:

> gpg --full-generate-key

gpg (GnuPG) 2.2.27; Copyright (C) 2021 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Please select what kind of key you want:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
  (14) Existing key from card
Your selection? 1
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (3072) 4096
Requested keysize is 4096 bits
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 
Key does not expire at all
Is this correct? (y/N) y

GnuPG needs to construct a user ID to identify your key.

Real name: your name
Email address: your_email@example.com
Comment: 
You selected this USER-ID:
    "your name <your_email@example.com>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
gpg: /home/user/.gnupg/trustdb.gpg: trustdb created
gpg: key F9F6F8A3107A2872 marked as ultimately trusted
gpg: directory '/home/user/.gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/home/user/.gnupg/openpgp-revocs.d/6C0951FFFA10BCD916C0A74BF9F6F8A3107A2872.rev'
public and secret key created and signed.

pub   rsa4096 2022-10-10 [SC]
      6C0951FFFA10BCD916C0A74BF9F6F8A3107A2872
uid                      your name <your_email@example.com>
sub   rsa4096 2022-10-10 [E]

To export your public GPG key to a file you need the key ID. Use following command to find it:

> gpg --list-secret-keys --keyid-format=long
sec   rsa4096/F9F6F8A3107A2872 2022-10-10 [SC]
      6C0951FFFA10BCD916C0A74BF9F6F8A3107A2872
uid                 [ultimate] your name <your_email@example.com>
ssb   rsa4096/6CDE17E943E85CD2 2022-10-10 [E]

In this case it’s F9F6F8A3107A2872.

gpg --output public.gpg --armor --export F9F6F8A3107A2872

Now export the private key:

gpg --output private.gpg --armor --export-secret-key F9F6F8A3107A2872

Delete/Import GPG Keys

To delete a GPG key use:

gpg --delete-secret-keys F9F6F8A3107A2872

To import a GPG key use:

gpg --import private.gpg

KeePassXC

First of all make sure SSH Agent integration is enabled and working in KeePassXC settings.

Now it’s time to store the keys in KeePassXC. Creating the entry is done in the same way for both SSH and GPG keys:

  1. Create a new entry, enter title and the password for the key
  2. “Open” the entry, select Advanced and add the private and public keyfile as attachments
  3. Select “SSH-Agent”, select the private key from the attachments

Now run ssh-add -l and check if your SSH key is listed. This indicates that your key is loaded in ssh-agent which can provide the key to other applications like git or ssh.

Github

Now head over to your github settings and add your public SSH and GPG key. To check if your SSH key is accepted run:

ssh -T git@github.com

To check the GPG key you need to push a signed commit. Enable GPG signing for all repositories in git (omit —global if you only want to enable it for a single repository):

git config --global commit.gpgsign true

Then tell git which key to use by providing the ID

git config --global user.signingkey F9F6F8A3107A2872

If you create a new commit git should automatically try to sign it:

git commit -m "test"

Now you should be able to see a ‘verified’ badge in your commit history on github ✨

Troubleshooting

error: gpg failed to sign the data

Try to add following line to your .bashrc:

export GPG_TTY=$(tty)

gpg: signing failed: No secret key

Make sure the keyId is correct:

git config --global user.signingkey F9F6F8A3107A2872

gpg: skipped “F9F6F8A3107A2872”: No secret key

Check if gpg.program points to a valid gpg binary:

git config --global gpg.program "/path/to/gpg"