Using a code signing certificate with Github And Yubikey

Published on Friday, 31 May 2019

So I was using GPG key to generate perform commit signing verification with GitHub based on the work from Geoffrey Huntley. He has a excellent post on using GPG.

This article explores using x509 certificates as verification sources and Yubikey.

This following guide will only work with Yubikey devices that have PIV support. You may be able to adapt this guide to other PIV enabled security devices.

You will need to get a code signing certificate from a verified certificate authority. GitHub uses the Debian CA certificate package to verify the SMime Certificate which is the same used by the Mozilla browser. I found DigiCert very good, they were able to do Skype notary public services for free, since notary services are expensive in Australia.

In this guide all the instructions are for windows but they can be adapted for other platforms with some modifications.

What's the motivation

So what's the motivation of doing commit signing for git?

  • People know that it's someone with access to your private key, and therefore ideally it's you.
  • GitHub will show that it's signed, so people start to build their confidence. With authorized certificate authorities GitHub will show the authority details in the verification.
  • Using a certificate authority the user knows that you have gone through physical ID checks to be issued the certificate.

What's the motivation for using a YubiKey?

  • Greater security for storing your private key. It gets stored on the YubiKey device and the only way to access it is with a passcode which must be entered once per session.
  • Optionally YubiKey's come with a touch button which generates a hash sequence.
  • Yubikey can be used for 2FA for GitHub website as well so you get extra security there also.

Yubikey Setup

First step is to get a X509 certificate from a authorised provider such as DigiCert, making sure your CSR request contains your GitHub email. Follow their instructions on how install and use the key.

On windows you can use a Yubikey Mini Smart Driver but I found the YubiKey manager approach detailed below easier.

I am assuming a pin policy of "once" per session, and no "touch" policy, there are other options. I am also installing into slot 9c which is the signing slot.

  1. Export out a PFX file from the X509 certificate. Make a backup in a safe location of this file, if someone gets it they can pretend to be you.
  2. Install the YubiKey manager.
  3. Open a command line.
  4. Run cd "%PROGRAMFILES%\Yubico\YubiKey Manager"
  5. Change your pin from the default (if you haven't already) and change from the default pin 123456. Run .\ykman piv change-pin -P 123456 -n <new pin>
  6. Run: .\ykman piv import-key --pin-policy=default 9d C:\path\to\your.pfx
  7. When prompted, enter the PIN, management key, and password for the PFX.
  8. Run: .\ykman piv import-certificate 9d C:\path\to\your.pfx
  9. When prompted, enter the PIN, management key, and password for the PFX.
  10. You may need to logout of your profile if the keys don't show up in SMIMESign below.

GitHub setup

I am going to assume you want to use S/MIME signing for all your repositories. There are other options in the GitHub guide. We are going to generate a batch file to run smimedesign due to a ongoing issue with timestamp authorities.

  1. Install S/MIME sign.
  2. Create a batch file that is in your path to smimedesign. For windows the batch file sample (which you could name sign.cmd)
    @echo off
    smimesign.exe --timestamp-authority %*
  3. Tell git to use smimesign. From the command line run:
    1. git config --global gpg.x509.program c:/path/to/sign.cmd
    2. git config --global gpg.format x509
    3. git config --global commit.gpgsign true
  4. Find the key you want to sign with. Run smimesign --list-keys and find the serial number of the key you wish to sign with. Copy the serial number of the key so you can paste it into the next command. Make sure you use the serial number not the ID.
  5. From the command line set the key to use git config --global user.signingkey a2dfa7e8c9c4d1616f1009c988bb70f

Now each time you commit it will ask you for a passcode that you set earlier.


comments powered by Disqus