Skip to content
Website Security

How to Set Up SSH Keys on Windows

In this article14 sections

To set up SSH keys on Windows, open PowerShell, run ssh-keygen -t ed25519 to create a key pair, copy the public half to your server’s ~/.ssh/authorized_keys file, and log in with ssh user@server. Windows 10 and 11 include the OpenSSH client, so there is nothing to install and no need for PuTTY. Once the key works, you can switch off password logins on the server, which stops password-guessing attacks completely.

This guide is for connecting from a Windows PC to a Linux server or VPS. It covers creating the key, getting it onto the server without the ssh-copy-id tool that Windows lacks, saving your connection settings, and fixing the errors people meet most often.

How keys work, in two sentences

A key pair is two files: a private key that stays on your PC and a public key that you can hand to any server. The server lets in whoever can prove they hold the private key, and nothing secret ever crosses the network, which is why keys are safer than passwords.

Step 1: Check that OpenSSH is there

Open PowerShell (press Start, type powershell, press Enter) and run:

ssh -V

You should see a version line such as OpenSSH_for_Windows_9.5p1. If the command is not found, open Settings → System → Optional features → Add a feature and install OpenSSH Client.

Step 2: Create the key pair

ssh-keygen -t ed25519 -C "yourname@laptop"

Press Enter to accept the suggested location. When asked for a passphrase, type one: it encrypts the private key on your disk, so a stolen laptop does not mean a stolen server. The text after -C is only a label, and it helps you recognise the key on a server later.

Two files now exist in the .ssh folder of your user profile:

File What it is Share it?
C:\Users\You\.ssh\id_ed25519 Private key Never
C:\Users\You\.ssh\id_ed25519.pub Public key Yes, with any server

Step 3: Copy the public key to the server

Linux and macOS have a helper called ssh-copy-id for this. Windows does not, but one line does the same job. Replace user@server with your own login and server address:

type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh user@server "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

You are asked for the server password one last time. The command creates the .ssh folder on the server if it is missing, adds your key to the list of accepted keys, and sets the strict permissions SSH insists on.

If your provider gave you a control panel with a field for an SSH public key, you can paste the key there instead. Print it with:

type $env:USERPROFILE\.ssh\id_ed25519.pub

It is a single line starting with ssh-ed25519. Copy all of it.

Step 4: Log in with the key

ssh user@server

This time you are asked for the key’s passphrase, not the server’s password, and you are in. If it still asks for the server password, the key was not accepted: go to the troubleshooting table below before changing anything else.

Step 5: Stop typing the passphrase every time

Windows has an agent that holds your unlocked key in memory. Switch it on once, in a PowerShell window opened with Run as administrator:

Get-Service ssh-agent | Set-Service -StartupType Automatic
Start-Service ssh-agent

Then, in a normal PowerShell window, add your key:

ssh-add $env:USERPROFILE\.ssh\id_ed25519

You type the passphrase once here, and logins after that need nothing. The agent remembers the key across restarts.

Step 6: Save your servers in a config file

Create a text file named config, with no extension, in the same .ssh folder:

notepad $env:USERPROFILE\.ssh\config
Host myvps
    HostName 203.0.113.20
    User deploy
    IdentityFile ~/.ssh/id_ed25519

Host shop
    HostName shop.example.com
    User admin
    Port 2222
    IdentityFile ~/.ssh/id_ed25519

Now ssh myvps is the whole command. The same names work in scp, in Git, and in editors such as VS Code that connect over SSH. If Notepad saved the file as config.txt, rename it: the file must have no extension.

Step 7: Switch off password logins on the server

Do this only after step 4 works. Keep your current session open, and on the server create a small settings file:

printf 'PasswordAuthentication no\nKbdInteractiveAuthentication no\n' | sudo tee /etc/ssh/sshd_config.d/00-keys-only.conf
sudo sshd -t && sudo systemctl reload ssh

The name starts with 00 so it is read before any other file in that folder, and the first value SSH reads is the one it uses. sshd -t checks the configuration and prints nothing when it is valid. Confirm the result:

sudo sshd -T | grep -i passwordauthentication

It should say passwordauthentication no. Now open a new PowerShell window and log in. Only when that works should you close the first session.

Warning. With passwords off, the private key is the only way in. Back it up before you rely on it, as described below, and make sure you know how to reach the server’s console through your provider if the key is ever lost.

When it does not work

You see Cause Fix
Still asked for the server password Key not in authorized_keys, or added for a different user Repeat step 3 with the exact user you log in as
Permission denied (publickey) Server accepts keys only and yours is not there, or permissions on the server are too open On the server: chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys
WARNING: UNPROTECTED PRIVATE KEY FILE! Other Windows accounts can read your private key, so SSH refuses to use it Run the icacls command below
Bad owner or permissions on .ssh/config Same problem, on the config file Same command, with config as the file name
REMOTE HOST IDENTIFICATION HAS CHANGED The server was reinstalled, or the address now points elsewhere If you expected it: ssh-keygen -R server-address. If you did not, stop and find out why
Could not open a connection to your authentication agent The agent service is not running Repeat step 5 as administrator

To restrict the private key to your own account:

icacls $env:USERPROFILE\.ssh\id_ed25519 /inheritance:r /grant:r "$($env:USERNAME):(R)"

For anything not in the table, add -v to the command (ssh -v user@server). The output shows which keys were offered and why each was refused.

Back up the key, and plan for losing it

  • Back up the private key file to an encrypted place, such as a password manager that stores files. With a passphrase on it, the backup is useless to anyone else.
  • Use a second key on a second device and add its public key to the server too. authorized_keys holds one key per line, as many as you like. Losing one device then costs you nothing.
  • Remove a key by deleting its line from authorized_keys on each server. This is where the label from step 2 earns its keep.

What about PuTTY?

PuTTY still works, but it uses its own key format (.ppk), and keys made with ssh-keygen must be converted with PuTTYgen before PuTTY can use them. Unless you have a reason to keep PuTTY, the built-in client is simpler: it uses the same commands and files as every Linux guide you will read, including the ones on this blog.

Common mistakes to avoid

  • Sending the private key to a server or a colleague. Only the .pub file ever leaves your PC.
  • Skipping the passphrase. Without one, anyone who copies the file has your servers.
  • Switching off passwords before testing the key. Test in a new window first, with the old session still open.
  • Adding the key for root and logging in as another user. Each user has their own authorized_keys.
  • One key, one device, no backup. A dead laptop then means a locked server.
  • Saving the config file as config.txt. SSH ignores it without telling you.

SSH keys on a SiteHarbour VPS

A SiteHarbour VPS is handed over with key-based login already in place: a non-root sudo user, SSH key login, and password login for root disabled, so the server side of this guide is set up before you receive it. If you are ever locked out, the next thing to check is the firewall, covered in how to set up a UFW firewall on Ubuntu, and the full list of checks is in the VPS security audit.

Frequently asked questions

Why ed25519 and not RSA?

Ed25519 keys are shorter, faster and at least as strong as a 3072-bit RSA key, and every current server supports them. Use RSA only for an old system that refuses anything else.

Can I use the same key for several servers?

Yes. Put the same public key on each one. Use separate keys when you want to cut off access to one group of servers without touching the others.

Does this work in Windows Terminal and VS Code?

Yes. Both use the same OpenSSH client, the same keys and the same config file.

Is the passphrase sent to the server?

No. It only unlocks the private key on your own PC. The server never sees it.

What if I lose the private key?

Log in with a second key if you added one. Otherwise use your provider’s console access to add a new public key to authorized_keys.

The short version: ssh-keygen -t ed25519, copy the .pub file’s contents into the server’s authorized_keys, test in a new window, then turn passwords off. Add the agent and a config file and logging in becomes ssh myvps.

Share this guide