OpenSSH Public Key Authentication on Windows —Not working? The secret tricks come out!

asheroto
3 min readMar 11, 2021

I figured out the trick to get OpenSSH public key authentication working on Windows.

Usually it’s not that complicated. But OpenSSH was not playing nice today.

This article assumes you have already installed OpenSSH through the installer, in the default directories, and have created a key pair using ssh-keygen with id_rsa and id_rsa.pub files in your .ssh user directory.

Example .ssh path: C:\Users\User\.ssh
Example sshd_config path: C:\ProgramData\ssh\sshd_config

If you perform these steps in order, you should have some success! 😊

Make sure you don’t have ANY instances of sshd or ssh-agent running (important):

  • Run PowerShell as Administrator:
Stop-Service sshd
Stop-Service ssh-agent
taskkill /f /im sshd.exe
taskkill /f /im ssh-agent.exe
  • Make sure you have these in your config and do not have duplicate lines
PubkeyAuthentication yes
PasswordAuthentication no
  • Starting with Win 10 build 1809 and later, apparently you need to comment out these lines (matching administrators and its authorized_keys file):
 Match Group administrators
AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys

- administrators_authorized_keys needs to include the lines from your user’s id_rsa.pub file (your public key file that contains the ssh-rsa command)

  • id_rsa and id_rsa.pub and administrators_authorized_keys need to be in UTF-8 (without BOM) character encoding. You can use this script to ensure all of them are.
function UTF8NoBom($filter) {
$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding($False)
foreach($i in ls -Recurse -Filter $filter) {
$MyFile = Get-Content $i.fullname
[System.IO.File]::WriteAllLines($i.fullname, $MyFile, $Utf8NoBomEncoding)
}
}
Set-Location “~/.ssh”
UTF8NoBom(“id_rsa*”)
Set-Location “$ENV:ProgramData\ssh”
UTF8NoBom(“*authorized_keys*”)
  • administrators_authorized_keys needs to have ONLY TWO permissions: SYSTEM and Administrators (important). Run this script in PowerShell as Administrator to fix the permissions on the file.
$ak = “$ENV:ProgramData\ssh\administrators_authorized_keys”
$acl = Get-Acl $ak
$acl.SetAccessRuleProtection($true, $false)
$administratorsRule = New-Object system.security.accesscontrol.filesystemaccessrule(“Administrators”,”FullControl”,”Allow”)
$systemRule = New-Object system.security.accesscontrol.filesystemaccessrule(“SYSTEM”,”FullControl”,”Allow”)
$acl.SetAccessRule($administratorsRule)
$acl.SetAccessRule($systemRule)
$acl | Set-Acl
  • Ensure those are the only two users:
Get-Acl “$ENV:ProgramData\ssh\administrators_authorized_keys” | Format-List

If you have more than SYSTEM and Administrators, go to the file and remove other users/groups.

  • id_rsa and id_rsa.pub need to have ONLY TWO permissions: SYSTEM and your username (important). Run this script in PowerShell as the user but running as Administrator to fix the permissions on the file.
$userRule = New-Object system.security.accesscontrol.filesystemaccessrule(“$(whoami)”,”FullControl”,”Allow”)
$systemRule = New-Object system.security.accesscontrol.filesystemaccessrule(“SYSTEM”,”FullControl”,”Allow”)
$idrsa = “~/.ssh/id_rsa”
$acl1 = Get-Acl $idrsa
$acl1.SetAccessRuleProtection($true, $false)
$acl1.SetAccessRule($userRule)
$acl1.SetAccessRule($systemRule)
$acl1 | Set-Acl
$idrsapub = “~/.ssh/id_rsa.pub”
$acl2 = Get-Acl $idrsapub
$acl2.SetAccessRuleProtection($true, $false)
$acl2.SetAccessRule($userRule)
$acl2.SetAccessRule($systemRule)
$acl2 | Set-Acl
  • Ensure those are the only two users:
Get-Acl “~/.ssh/id_rsa” | Format-ListGet-Acl “~/.ssh/id_rsa.pub” | Format-List

If you have more than SYSTEM and your username, go to the file and remove other users/groups.

  • Remaining in PowerShell as the user but running as Administrator, start the authentication agent:
Start-Service ssh-agent
  • Add the user account to the authentication agent:
ssh-add
  • Start the sshd service:
Start-Service sshd

It should be working now. 👍

If you are still having issues, run:

FixHostFilePermissions.ps1
FixUserFilePermissions.ps1

Both of these scripts should be located in the OpenSSH installation folder, although you should be able to execute them from anywhere if it’s installed correctly. For me, that path is C:\Program Files\OpenSSH-Win64.

After completing the above steps using this sshd_config file, I am able to log in using public key authentication.

--

--

asheroto

🌎 Full Stack Developer 🔗 Systems Administrator 😎Innovation through Automation ✔ Privacy Advocate ♥ Startup Facilitator