Skip to content
Launch offerNew accounts: we double your first deposit of $100 or more, up to $250 bonus.Claim my bonus
LiteKeep
Sign inDeploy a server

Step-by-step tutorial, 2026

How to generate an SSH key on Windows. Tested, start to finish.

Every command on this page was run on a real Windows 11 PC against a real Linux server, and the terminal output you see is what came back. Including the errors.

  • 14 min read
  • 11 chapters
  • Updated

Your Windows PC

id_ed25519Private key. Never leaves this PC.
id_ed25519.pubPublic key. Safe to share.

Your server

~/.ssh/authorized_keysOne line per key it trusts.
Login: the server checks you hold the matching private key. No password crosses the wire.

The short answer

Open PowerShell and run ssh-keygen -t ed25519. Press Enter to keep the location, type a passphrase twice, and your key pair lands in C:\Users\you\.ssh: id_ed25519 stays on your PC, id_ed25519.pub goes to the server.

Windows has no ssh-copy-id, so copy the public key with one PowerShell line (below), then log in with ssh user@your-server. Our free command builder fills in every command for your server.

Passwords get guessed. Our own server saw more than 14,000 password attempts in its first three days online.

An SSH key can’t be guessed. It’s a pair of files: a private key that never leaves your PC, and a public key you hand to the server. When you log in, the server checks that you hold the matching private key. No password crosses the internet at all.

Here’s the catch. Most Windows guides stop after ssh-keygen. Then they tell you to run ssh-copy-id, which Windows doesn’t have. Several still say the default key type is RSA, which stopped being true in 2023.

So we did it properly. We ran every step on Windows 11 against an Ubuntu 24.04 server, broke it on purpose four different ways, and wrote down exactly what each error looks like and how to fix it.

In this guide you’ll learn

  • Check that OpenSSH is on your PC, in one command
  • Create an Ed25519 key, with a passphrase and a label that doesn’t leak your name
  • Copy it to your server without ssh-copy-id
  • Log in with one word using a config file and ssh-agent
  • Use it in PuTTY, and convert between PPK and OpenSSH
  • Fix “Permission denied (publickey)” with the real server logs

Chapter 1

The short answer

Here’s the whole job in four PowerShell commands. Replace [email protected] with your server’s user and address, or let the builder below do it.

SSH keys on Windows, in four steps
StepCommandWhat it does
1. Checkssh -VConfirms the built-in OpenSSH client is installed
2. Createssh-keygen -t ed25519 -C "laptop-2026"Makes id_ed25519 and id_ed25519.pub in C:\Users\you\.ssh
3. CopyThe one-liner in step 3 belowAdds your public key to ~/.ssh/authorized_keys on the server
4. Connectssh [email protected]Logs in with the key instead of a password

Chapter 2

Get your exact commands

Type your server’s address, user and port. The builder writes every command in this tutorial for your server, in the same form we tested. It runs only in your browser.

Your server

Nothing you type leaves this page.

1. Create the key
ssh-keygen -t ed25519 -C "laptop-2026" -f "$HOME\.ssh\id_ed25519"

Press Enter to accept the file, then type a passphrase twice.

2. Copy it to the server
$pubKey = (Get-Content "$HOME\.ssh\id_ed25519.pub" | Out-String); ssh [email protected] "mkdir -p ~/.ssh && chmod 700 ~/.ssh && echo '$pubKey' >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

Asks for your server password one last time.

3. Log in with the key
ssh -i "$HOME\.ssh\id_ed25519" [email protected]
4. Save a shortcut (add to %USERPROFILE%\.ssh\config)
Host myvps
    HostName 203.0.113.10
    User root
    IdentityFile ~/.ssh/id_ed25519
    IdentitiesOnly yes

Then just type: ssh myvps

If Windows says UNPROTECTED PRIVATE KEY FILE
icacls "$HOME\.ssh\id_ed25519" /inheritance:r
icacls "$HOME\.ssh\id_ed25519" /grant:r "${env:USERNAME}:R"

No server yet? Deploy a Lite 2 and paste your .pub key at deploy: you skip step 2 and log straight in. Billed by the hour.

Each step below explains what these commands do and what you should see, so you’re never pasting blind.

Chapter 3

Step 1: Check OpenSSH is installed

Windows ships Microsoft’s build of OpenSSH, the same software Linux and macOS use. Open PowerShell (press Start, type PowerShell) and ask it for its version:

PS C:\Users\you> ssh -V
OpenSSH_for_Windows_9.5p2, LibreSSL 3.8.2
PS C:\Users\you> Get-Service ssh-agent | Select-Object Status, StartType

Status  StartType
------  ---------
Stopped  Disabled
Our Windows 11 25H2 PC already had the OpenSSH client. The ssh-agent service was installed but disabled, which matters in step 6.

If you see a version, skip to step 2. If PowerShell says ssh isn’t recognised, install it. OpenSSH has been an optional Windows feature since Windows 10 build 1809:

  • Windows 11: Settings, System, Optional features, View features, then search for OpenSSH Client and add it.
  • Or in PowerShell as administrator: Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0

Chapter 4

Step 2: Create your key

Run this in PowerShell. You don’t need administrator rights:

ssh-keygen -t ed25519 -C "laptop-2026"

It asks three things: where to save the key (press Enter for the default), then a passphrase, twice. Here’s what comes back:

PS C:\Users\you> ssh-keygen -t ed25519 -C "litekeep-test"
Generating public/private ed25519 key pair.
Your identification has been saved in C:\Users\you\.ssh\id_ed25519
Your public key has been saved in C:\Users\you\.ssh\id_ed25519.pub
The key fingerprint is:
SHA256:JKnwhfyuOT429Sv/HeX4e/KgruZKIptps4IqhTB3SAU litekeep-test
The key's randomart image is:
+--[ED25519 256]--+
|  Eo.            |
|  .. . .         |
| ...o + .        |
|o oo.+ o         |
|.+ .o . S     .  |
|. .  ..      +   |
| o  ..o..   o o  |
|o . BB.o. .. +...|
|+  =O* o+*+o+ o=.|
+----[SHA256]-----+
Our run, labelled litekeep-test. We gave the file name and a test passphrase on the command line, so the prompts don't show here; yours will ask for the location and the passphrase twice. Paths shortened to C:\Users\you. The fingerprint and picture are unique to every key.

Why Ed25519?

It’s short, fast and strong, and it’s been the default since OpenSSH 9.5 in 2023. On our PC, plain ssh-keygen made an Ed25519 key too. We still type -t ed25519 so the command works the same on older builds. Only use RSA (-t rsa -b 4096) for an old system that rejects Ed25519.

Use a passphrase

The passphrase encrypts the private key file. If your laptop is stolen, the key is useless without it. Don’t leave it empty. Step 6 shows how to type it once per session instead of every time.

Mind the label

The text after -C is a comment saved inside the public key. Without it, OpenSSH fills in your user@host: your Windows username and your PC’s name. That label ends up on every server you add the key to. Most tutorials tell you to put your email there. Use something neutral that tells you which device it is.

Chapter 5

Step 3: Put the public key on your server

The server needs your public key in a file called ~/.ssh/authorized_keys. On Mac and Linux, ssh-copy-id does that. Windows doesn’t include it, so use this one line instead:

$pubKey = (Get-Content "$HOME\.ssh\id_ed25519.pub" | Out-String); ssh [email protected] "mkdir -p ~/.ssh && chmod 700 ~/.ssh && echo '$pubKey' >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

It reads your public key, logs in one last time with your password, creates the .ssh folder if needed, adds the key, and sets the permissions the server insists on: 700 for the folder, 600 for the file. In our test it finished silently, which is what success looks like.

  • Deploying on LiteKeep? Paste the contents of id_ed25519.pub when you deploy the server and skip this step entirely. Your first login already uses the key.
  • Different SSH port? Add -p 2222 after ssh. The builder above does it for you.
  • Never send the file without .pub. That’s your private key.

MythYou need ssh-copy-id from a third-party installer.

Fact

You don’t. It only appends one line to a text file, and the PowerShell line above does exactly that, with the right permissions.

MythThe public key is secret.

Fact

It’s meant to be shared. The private key, the file with no extension, is the one to guard.

Chapter 6

Step 4: Log in with your key

Now connect. OpenSSH tries id_ed25519 automatically, so this is usually all you need:

ssh [email protected]

The first time, it shows the server’s fingerprint and asks if you trust it. Compare it with your server’s fingerprint if you have it, then type yes. It’s saved in known_hosts and won’t ask again.

Then it asks for your key’s passphrase, not the server password. That difference is how you know the key worked. If you saved the key under another name, point at it with -i:

ssh -i "$HOME\.ssh\id_ed25519" [email protected]

Chapter 7

Step 5: Log in with one word

Typing users, addresses and ports gets old. OpenSSH on Windows reads a config file at %USERPROFILE%\.ssh\config. Create it in Notepad (no file extension) and add:

Host myvps
    HostName 203.0.113.10
    User user
    IdentityFile ~/.ssh/id_ed25519
    IdentitiesOnly yes

Now ssh myvps is the whole command. In our test, a config like this logged straight in. Add Port 2222 if you use a different port, and one Host block per server.

IdentitiesOnly yes tells SSH to offer only that key. Without it, a PC with many keys can hit the server’s limit on attempts before the right key gets its turn.

Chapter 8

Step 6: Type your passphrase once

ssh-agent holds your unlocked key in memory, so you type the passphrase once instead of on every connection. On Windows the agent is disabled by default, and on our PC it was.

Open PowerShell as administrator once and run:

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

Then, in a normal PowerShell window, add your key and type the passphrase one last time:

ssh-add "$HOME\.ssh\id_ed25519"

From now on, ssh myvps connects without asking. Automatic keeps the agent running after a restart; Manual would mean starting it yourself each time.

Chapter 9

Using PuTTY or PuTTYgen instead

Some tools, like WinSCP and older PuTTY setups, want keys in PuTTY’s own .ppk format. PuTTYgen converts in both directions.

  • OpenSSH key to PPK: open PuTTYgen, choose Conversions, Import key, pick id_ed25519, enter its passphrase, then Save private key.
  • PPK to OpenSSH: Load the .ppk, then Conversions, Export OpenSSH key.
  • The public key for the server is the box labelled Public key for pasting into OpenSSH authorized_keys file. Copy from there, not from the “Save public key” file, which uses a different, multi-line format the server won’t accept.
  • Old PuTTY? New PPK files are version 3. Only PuTTY 0.74 and older need version 2.

Chapter 10

Fix “Permission denied (publickey)”

This message is frustrating because it’s the same for every cause. We triggered each cause on our test server. Here’s what the client said, what the server’s log said, and the fix. For all twelve causes we reproduced, and a free error decoder, see our Permission denied (publickey) guide.

Every cause we tested, with the server's own log line
CauseServer log saysFix
Wrong user nameInvalid user deployUse the user the key was added for, often root on a new server
Wrong key offeredConnection closed … [preauth], no reason givenPoint at the right key with -i, or IdentityFile in the config
authorized_keys writable by everyone (666)bad ownership or modes for file …/authorized_keyschmod 600 ~/.ssh/authorized_keys
.ssh folder writable by everyone (777)bad ownership or modes for directory …/.sshchmod 700 ~/.ssh
Private key readable by others on WindowsNothing: the client refuses before sending itThe icacls fix below

A surprise from our test: making authorized_keys group-writable (664) did not break login, because OpenSSH allows it when the group contains only you. Many guides say any loose permission breaks it. Only world-writable did.

See which key SSH is offering

Add -v and look for these lines:

PS C:\Users\you> ssh -v -i .\other_key [email protected]
debug1: Authentications that can continue: publickey
debug1: Offering public key: .\other_key ED25519 SHA256:EMQ9pBYv… explicit
debug1: Authentications that can continue: publickey
debug1: No more authentication methods to try.
[email protected]: Permission denied (publickey).
Trimmed from our run with the wrong key; the key file, user and address are replaced with this page's examples. 'explicit' means the key came from -i. The server accepted none, so SSH gave up.

“UNPROTECTED PRIVATE KEY FILE” on Windows

If other accounts can read your private key, OpenSSH refuses to use it. We gave Everyone read access to a copy of our key to see it happen:

Bad permissions. Try removing permissions for user: \Everyone (S-1-1-0) on file C:/Users/you/.ssh/id_ed25519.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions for 'C:\Users\you\.ssh\id_ed25519' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
[email protected]: Permission denied (publickey).
The real warning; the file path, user and address are replaced with this page's examples. The key was ignored, so the login failed.

The fix: remove inherited permissions and give only yourself read access. These two lines fixed it in our test (if the warning names an account, like Everyone, also run icacls "$HOME\.ssh\id_ed25519" /remove Everyone):

icacls "$HOME\.ssh\id_ed25519" /inheritance:r
icacls "$HOME\.ssh\id_ed25519" /grant:r "${env:USERNAME}:R"
  1. Right user?How to check: The key is added per user. root and deploy have separate authorized_keys files.
  2. Right key?How to check: Run with -v and check the “Offering public key” line.
  3. Server permissions?How to check: chmod 700 ~/.ssh and chmod 600 ~/.ssh/authorized_keys, run on the server.
  4. Key on one line?How to check: Each key in authorized_keys must be a single line starting with ssh-ed25519.
  5. Lost the .pub file?How to check: ssh-keygen -y -f "$HOME\.ssh\id_ed25519" prints it again from the private key. It worked in our test.

Chapter 11

Next: close the password door

Your key works. But while password logins stay on, bots can keep guessing. The last step is to turn passwords off on the server.

Do it in the order our VPS security guide lays out: create your own sudo user, give it your key, test in a second window, and only then disable root and password logins. Its free generator writes the commands for your server.

  • New laptop? Make a new key on it and add that one too. Don’t copy private keys between machines.
  • Lost a device? Delete its line from ~/.ssh/authorized_keys on every server.
  • Running Windows Server too? Admin accounts there use administrators_authorized_keys in C:\ProgramData\ssh, not the file in your user folder.

Need a server to try this on? A Lite bills by the hour, so a practice run costs cents. Deploy a Lite 2 with your new key pasted in, and your first login is already passwordless. Or run Windows itself on a Windows VPS.

Now it’s your move

That’s the whole thing: one key pair per device, the public half on each server, a passphrase you type once per session, and a config file that turns every login into one word.

If something goes wrong, the error is almost always one of the five causes above, and -v plus the server log will point at it.

Your key is ready. Give it a server. Paste it in when you deploy a Lite, log in with one word, and pay only for the hours it runs.