Windows - Using GPG for SSH authentication (and Git)

Windows can use GPG for SSH auth just like Linux, although the configuration is a bit different. You can even use your same GPG smartcard so private keys don't need to be sitting around on your disk.

Install & Setup Gpg4win

Only the command line tools need to be installed. I'm not going to cover setting up keys as it's identical to Linux.

For smartcard usage just importing your public key and setting the trust level is needed. Windows should automatically install drivers for a smartcard when it's plugged in.

Setup gpg-connect-agent

When logging in, gpg-connect-agent /bye needs to be called. There are a lot of ways to do this. Here's the PowerShell scheduled job I use:

powershell
$job = Register-ScheduledJob `
	-Name GpgAgent `
	-ScriptBlock { gpg-connect-agent.exe /bye } `
	-Trigger (New-JobTrigger -AtLogOn -User $([System.Security.Principal.WindowsIdentity]::GetCurrent().Name)) `
	-ScheduledJobOption (New-ScheduledJobOption -StartIfOnBattery -ContinueIfGoingOnBattery) `
	-RunNow

# Change principal to run only on interactive logon instead of S4A.
$principal = New-ScheduledTaskPrincipal -LogonType Interactive -UserId $([System.Security.Principal.WindowsIdentity]::GetCurrent().Name)
Set-ScheduledTask -TaskPath \Microsoft\Windows\PowerShell\ScheduledJobs\ -TaskName $job.Name -Principal $principal

Install PuTTY

PuTTY is used as a replacement for OpenSSH since it works with Gpg4win via Pageant.

Once installed, authenticating with remote hosts from PuTTY should work, and it should prompt for a smartcard PIN if needed.

Enable PuTTY support in GPG

Add the following line to %APPDATA%\gnupg\gpg-agent.conf:

enable-putty-support

Configuring Git to use Gpg4win and PuTTY

Add an environment variable to direct Git to use plink instead of the builtin OpenSSH:

powershell
[System.Environment]::SetEnvironmentVariable('GIT_SSH', 'C:\\Program Files\\PuTTY\\plink.exe', [System.EnvironmentVariableTarget]::Machine)

Git on Windows uses its own bundled GPG, so direct it to use Gpg4win in .gitconfig:

conf
[gpg]
	program = C:/Program Files (x86)/GnuPG/bin/gpg.exe

Usage

Everything should now 'just work' for push/pull/signing in Git. One caveat with Git is that when a server fingerprint isn't recognized it cannot be added to known hosts via the command line as input isn't recognized. The workaround for this is to first connect via PuTTY.