DEV Community

Cover image for Setting up git+ssh+gpg on Windows
Mihail Malo
Mihail Malo

Posted on • Edited on

Setting up git+ssh+gpg on Windows

Sometimes we all end up having to use Windows.
I was trying to avoid this, but it sneaks up on you.
So, how does one set up basic git with SSH authentication and GPG commit signing, for VS Code and command line?
Maybe I was spoiled by Linux community documentation, but I basically didn't get an answer. So, today we investigate!

Not in scope: We won't be:

  • generating the SSH identity with ssh-keygen -t rsa -b 4096 -C "YOUR.ACTUAL@MAIL.HERE"
  • or GPG key with gpg --generate-key,
  • nor adding them to https://github.com/settings/keys.

This article assumes you want to use your existing keys. But all these are well-documented. If you disagree and would like me to post a writeup on those, please leave a comment.

We will be using scoop instead of chocolatey, so that our setup is unprivileged and confined to the local user.

We'll assume you don't have anything installed.
So let's open up PowerShell (not as administrator) and begin:

Scoop

# Enable powershell executables
Set-ExecutionPolicy RemoteSigned -scope CurrentUser
# Install scoop
iex (new-object net.webclient).downloadstring('https://get.scoop.sh')

# scoop uses aria2 for parallel downloads
scoop install aria2
Enter fullscreen mode Exit fullscreen mode

Git

scoop install git
Enter fullscreen mode Exit fullscreen mode

Now, if you are on Windows 10 and don't follow Windows news,
run ssh -V and prepare to be shocked.
Since April 2018, Windows ships with OpenSSH!

some reports indicate that you may have to activate the feature as follows (I didn't have to):

Add-WindowsCapability -Online -Name OpenSSH.Client*

Since we are going for a minimal setup here, we will not install our own version.
We still have to add an environmental variable for git to start using it, though:


Enter fullscreen mode Exit fullscreen mode

Don't forget to restart PowerShell / VS Code or wherever you plan to use git after this to load the environmental variable.

Now, let's continue configuring git:

git config --global user.name "YOUR ACTUAL NAME HERE"
git config --global user.email YOUR.ACTUAL@MAIL.HERE
Enter fullscreen mode Exit fullscreen mode

Let's print the config to verify, it should look something like this:

git config -l --global
# user.email=YOUR.ACTUAL@MAIL.HERE
# user.name=YOUR ACTUAL NAME HERE
# credential.helper=manager
Enter fullscreen mode Exit fullscreen mode

Now, let's add our actual key to ssh:

ssh-add YOUR\KEY\PATH\id_rsa
Enter fullscreen mode Exit fullscreen mode

Note: If your key is located at ~/.ssh/id_rsa, and you have pshazz installed, you can (re)open a powershell, and pshazz will run ssh-add, adding it automatically (this will prompt you for the passphrase if you have one). I don't find it particularly valuable to keep your key there on Windows, so you can ssh-add it and then remove the file.

Now, assuming you will be using GitHub (similar for gitlab et al.), let's do a test connection (and save GitHub's signature, otherwise VS Code will get confused and silently fetch forever):

ssh -T git@github.com
# The authenticity of host 'github.com (192.30.253.112)' can't be established.
# RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8.
# Are you sure you want to continue connecting (yes/no)? yes
# Warning: Permanently added 'github.com,192.30.253.112' (RSA) to the list of known hosts.
Enter fullscreen mode Exit fullscreen mode

At this point, we have working git, but the commits will not get signed yet.

GPG

Now, the git package comes with a gpg executable, at:

# It's my first time writing powershell, any advice welcome
join-path (scoop prefix git) 'usr\bin\gpg.exe'
Enter fullscreen mode Exit fullscreen mode

Let's temporarily alias it to gpg!

sal gpg (join-path (scoop prefix git) 'usr\bin\gpg.exe')
Enter fullscreen mode Exit fullscreen mode

Aside: sal is an alias (wow, much meta) for Set-Alias.
But according to alias alias, alias isn't an alias for Get-Alias? 🤔🤔🤔

In my case it's a slightly older version than is available standalone.

scoop info gpg
gpg --version
Enter fullscreen mode Exit fullscreen mode

But, once again, we're going for a minimal setup.
So, let's just jam our key right on in there.

# Enable signing all commits by default
git config --global commit.gpgsign true
Enter fullscreen mode Exit fullscreen mode

Now, let's import our key:

gpg --import C:\YOUR\KEY\LOCATION\_SOMETHNG_-private.{key,gpg}
Enter fullscreen mode Exit fullscreen mode

You may also want to ultimately trust your key:

$(echo trust; echo 5; echo y; echo quit) | gpg --command-fd 0 --edit-key YOUR.ACTUAL@MAIL.HERE
Enter fullscreen mode Exit fullscreen mode

It is fine to remove your key file after this, it was imported into the gpg install.

Finally, let's install some more packages:

# the default bucket doesn't include GUI applications such as VS Code
scoop bucket add extras

# check for (self)updates
scoop update
scoop update *

# install the good nice things
scoop install vscode pshazz
Enter fullscreen mode Exit fullscreen mode

🎉 We are done! 🎉

The result should look like this:

git config -l --global
# user.email=YOUR.ACTUAL@MAIL.HERE
# user.name=YOUR ACTUAL NAME HERE
# credential.helper=manager
# commit.gpgsign=true

gpg -K
# C:/Users/YOUR_NAME/AppData/Roaming/gnupg/pubring.kbx
# ------------------------------------------------
# sec   rsa4096 2017-10-18 [SC]
#       8E84465BB27D2E97F5B379C0D41763D409EF23A0
# uid           [ultimate] YOUR ACTUAL NAME HERE <YOUR.ACTUAL@MAIL.HERE>
# ssb   rsa4096 2017-10-18 [E]
Enter fullscreen mode Exit fullscreen mode

To test signing, make a commit:

git init git-signature-test
pushd git-signature-test
echo "" > butts
git add butts
git commit -m Init
git log --show-signature
popd
rm -r -fo git-signature-test
Enter fullscreen mode Exit fullscreen mode

The output should include "Good signature from" followed by YOUR ACTUAL NAME HERE <YOUR.ACTUAL@MAIL.HERE>.

Edit: It seems like we installed the whole scoop mostly just to get git :)
Originally this article included installing your own OpenSSH and GPG, and even something from chocolatey, but after reading GitHub issues and experimenting, it turned out that just this is plenty. 🎉

Top comments (3)

Collapse
 
lengthmin profile image
Artin

Thanks for the alias!

help me a lot.

Collapse
 
phocks profile image
Joshua Byrd

My Windows didn't have ssh pre-installed, but was able to do it using this method :) anto.online/guides/how-to-install-...

Collapse
 
qm3ster profile image
Mihail Malo • Edited

I wonder what activated this feature for me, then.
Perhaps it was VSCode, or its Remote - SSH extension?