... So I seem to make a habit of not posting very often! Oh well. Here is another dive into the insanity.
So, recently I have been getting a bit more into OpenPGP, and the ecosystem that exists around it for various things such as authentication, signing, and using it as your proof of identity in the digital world. It's been something that has been on the edge of my radar for a long time, however at the recent Freenode Live conference, I got talking to a representative of Yubico, who produce the Yubikey - and managed to get hold of one of them! This brought the OpenPGP stuff a lot closer to the center of my radar, and so I started digging a lot more into the information around it.
Now, I am planning on going a lot more into depth on the setup and maintanence of your own OpenPGP key pair, and going through the reasoning behind a lot of the various decisions such as an offline master key etc., however for this post I will go over the items for getting GPG and Windows to play nicely for Authentication and Signing, specifically using Putty and Git.
What do you want?
So the main aim of this, is to allow me to use git, PuTTY (for ssh), and Powershell to all play together with GnuPG, so I can develop wherever I am, on whatever machine or OS I chose. My default development system is either Debian or Ubuntu (depending on how I'm feeling and how much time I want to spend setting up my system...) which has great integration between git, OpenSSH, GnuPG, and the myriad of shells available. But is this possible on a Windows system under Powershell?
Well, the answer is actually 'mostly' - there are a few things which dont work, or I couldnt figure out how to get to work, but most of it can be done:
- Authentication for SSH and Git
- Signing Commits using GPG
- Compatibility with Yubikey
The one thing that I have not managed to figure out, and have found no evidence of ever working under Windows however, is:
- Forwarding GPG agent over SSH
Now, this may just be me missing something, however there is only one post I can find with any hint of it ever working, so if anyone knows how to get this to work I would be grateful!
So lets get started, shall we?
The Toolset
The main software used for this is as you would imagine: all the windows versions for the various parts. So we need PuTTY, Gpg4Win, and Git for Windows. Fairly obvious stuff for this. Install all 3 of them, and then we can start getting things set up! For Gpg4Win, I reccomend the Kleopatra interface which is a Windows version of the software from KDE - I have not personally tried the alternative GUI, so config settings may be in different places.
All (config) Change...
Now, I will not go over getting your GPG key into Kleopatra here (wait for a
future post! I promise!) But the main config you will want to change is
enabling ssh, and putty support. For this, go into the Kleopatra interface,
click Settings -> Configure Kleopatra...
and then navigate to the GnuPG
System
menu, and select the Private Keys
tab. In here, tick the following
options:
- Enable ssh support
- Enable putty support
Then apply these settings, and you can close Kleopatra. You will need to get the GPG agent to restart, so open up a Powershell console and run the following commands:
gpg-connect-agent killagent /bye
gpg-connect-agent /bye
This will kill your current agent, and then start a new one for you with the ssh and putty settings loaded.
The next thing to do, is to get GPG to play well with Git. For this you will
need to add a new Environment Variable, so that Git uses PuTTY for connecting
via SSH, instead of its own binary which is included in the install. To get to
this, either use the Windows Menu search, looking for environment
, or right
click on the Windows Logo, select System, then on the right hand side (or below
if your screen is not that wide), select System info
, then select Advanced
system settings
.
If you searched for environment
in your Windows Menu, this is where you
rejoin us! In this new window, there should be an Advanced tab (possibly
already open) - select this, then at the bottom select Environment
Variables...
. This will bring up the environment variables dialog. In here,
you will want to create a new User variable for yourself, so click New...
,
and then add the following settings:
- Variable Name:
GIT_SSH
- Variable Value:
C:\Program Files\PuTTY\plink.exe
This is going to tell git to use the plink
software, which is provided by
PuTTY to allow normal ssh-based apps to use the PuTTY Pageant agent - which
Gpg4Win emulates when you enable ssh and putty support! The path to your
particular plink executable may be slightly different, if you installed the non
x64 version - you can use the browse option to find the exact version.
So, this has got all the various parts mostly set up - restart your Powershell instances and you should now be able to authenticate and sign your commits using GPG. There is one issue though...
Restarting Windows
When you restart, GPG does not automatically start itself up. This can be
annoying, but all you really need to do is start Kleopatra, or go to the
command line and run gpg-connect-agent /bye
to get one started. This is
annoying though, and there IS a way to start it automatically.
For this, you will need to add a link to your startup directory. The easiest
way to get to this is with win + r and then
type in shell:Startup
, which will open your Startup programs folder for you
in explorer.
In here, create a new shortcut which has the following target:
"C:\Program Files (x86)GnuPG\bin\gpg-connect-agent.exe" /bye
Note the /bye
at the end. Save this, and then open up its properties, and
then change the Run option to Minimized
- this means you dont get the cmd
prompt opening up when you start, which is just frankly annoying.
Now when you restart your machine, gpg is running ready for you! Yay!
git signing
Now, with Git you can sign your commits, and setting that up can either be done
globally or per repo. I use per repo settings, though it is really easy to set
it up globally with git - just add --global
to any of the config lines
following.
The first thing you will need to do is get git to see your GPG client. This is one of the few commands which makes sense being global, so set that with:
git config --global gpg.program "C:\Program Files (x86)GnuPG\bin\gpg.exe"
Adjusting the path as you need to. The next thing is to tell git what your signing key is, which means you need to find that out. To get all the fingerprints for your keys and subkeys, run the following (with your key id instead of the placeholder)
gpg --fingerprint --fingerprint test@example.com
Note putting fingerprint twice - this is not a typo, as only putting it once
will only show your master key fingerprint. Find your signing key from within
those (it will be the one with the S
in the square brackets before it). Take
the last 2 blocks of the fingerprint, and then set those as your signing key in
git - so if you see this output:
pub rsa4096 2017-11-10 [C] [expires: 2019-11-10]
F1AF 80A1 590E 129F 53D8 EFE1 9F3D 7300 D365 4BC7
uid [ultimate] Thomas Bloor <tbsliver@shadow.cat>
uid [ultimate] Thomas Bloor <t.bloor@shadowcat.co.uk>
sub rsa4096 2017-11-10 [S] [expires: 2018-11-10]
091A 035A F749 9D18 129F EA5F 8775 E856 E275 4827
sub rsa4096 2017-11-10 [E] [expires: 2018-11-10]
9640 D5B4 2E52 446B 5D2D 7499 2CDA 5FD0 AF33 4F0D
sub rsa4096 2017-11-10 [A] [expires: 2018-11-10]
E7F5 E7D5 AB40 631A 984B 14F9 C38A F658 6A78 53A7
Then your signing key for git would be E2754827
. (Yes, those are my work GPG
key fingerprints!) From this, you can set your signing key like so:
git config gpg.signingKey ABCDEF01
With this, you have to explicitly tell git to sign your commits using the -S
option. If you want git to always sign, then set this config as well:
git config commit.gpgsign true
And now git will always attempt to sign your commits - note that if you are using a Yubikey or other GPG card and dont have it plugged in, then the commit will fail and you'l have to rewrite your commit message.
Thats all folks!
So thats about it - now you can set up Git, GPG, and PuTTY on Windows, and have the same ability to sign commits and work on the command line as you can in Linux! If anyone knows how to get GPG key forwarding over SSH from Windows then that would be excellent, and let me know in the comments if you can see any improvements or need some more clarity on how this all works!