Migrate to RunxBuild and earn up to $50 in hosting credit on your first deposit.

Calculate your savings
unxBuild

Generate an SSH Key on Windows: Three Working Methods

Sean

Platform Writer

Jul 05, 2026
6 min read

Generating an SSH key on Windows takes one command in PowerShell (ssh-keygen -t ed25519), one GUI flow in PuTTYgen, or one command in WSL. All three produce the same kind of key - the difference is the format and where the file lands. The team that picks the right tool for their client (native OpenSSH vs PuTTY vs WSL) avoids the most common Windows-SSH friction.

Generate an SSH Key on Windows: Three Working Methods

Table of contents

PowerShell: the native path

PowerShell has OpenSSH built in on Windows 10 1809+ and all current Server SKUs:

ssh-keygen -t ed25519 -C "[email protected]"

The key lands in $env:USERPROFILE\.ssh\id_ed25519. The passphrase prompt is optional - the team that uses a passphrase on dev keys and a separate no-passphrase key for CI/CD has the right setup. The team that uses one key for both has a single compromise vector.

ssh-keygen may not be on PATH if OpenSSH was installed manually. Get-Command ssh-keygen shows which one is found. The team that has Git for Windows installed has a second ssh-keygen.exe in C:\Program Files\Git\usr\bin - both work the same way but the system one is usually more current.

CMD: the legacy path

CMD’s ssh-keygen is the same binary, the same arguments:

ssh-keygen -t ed25519 -C "[email protected]"

The path expansion %USERPROFILE% works in CMD. dir %USERPROFILE%\.ssh shows the new files. The team that prefers CMD over PowerShell for one-liners is fine here - there is no functional difference for key generation.

Both PowerShell and CMD share %USERPROFILE% as the home directory, so the .ssh folder ends up at the same path. The team that has multiple Windows accounts on the same machine has separate .ssh folders per user - Windows handles this automatically.

PuTTYgen: the .ppk path

PuTTYgen is the GUI tool that ships with PuTTY. The team that needs a .ppk (for older PuTTY clients, WinSCP, or some network gear) uses PuTTYgen:

  1. Launch PuTTYgen (usually in C:\Program Files\PuTTY\).
  2. Parameters: ed25519, 256 bits.
  3. Click Generate and move the mouse in the blank area to seed randomness.
  4. Set a passphrase.
  5. Save private key -> id_ed25519.ppk.
  6. Copy the public key text from the top box for authorized_keys.

The team that already has an OpenSSH-format key and wants a .ppk: open PuTTYgen, Conversions -> Import key, load the existing id_ed25519, save as .ppk. That conversion is one-way - the .ppk is PuTTY’s format and not interchangeable with OpenSSH.

WSL: the Linux path

WSL gives the team a full Linux environment with the real ssh-keygen:

wsl ssh-keygen -t ed25519 -C "[email protected]"

The key lands at ~/.ssh/id_ed25519 inside WSL’s filesystem - that is \\wsl$\Ubuntu\home\<user>\.ssh\ from Windows. The team that uses VS Code’s Remote - WSL extension can use the same key from both contexts.

The trap: WSL’s ~/.ssh is a different directory than Windows’ ~/.ssh. They do not share files by default. The team that creates a key in WSL and wants to use it from native PowerShell SSH needs to copy it: cp ~/.ssh/id_ed25519 /mnt/c/Users/you/.ssh/ (then chmod 600 on the Windows-side copy). The team that goes the other direction (Windows key into WSL) does the inverse.

Where the public key goes

The generation is half the work. The other half is installing the public key on the server:

Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub | ssh user@server "Add-Content -Path ~/.ssh/authorized_keys -Value $(Get-Clipboard)"

That one-liner reads the public key, copies it to the clipboard, and pipes it into the server’s authorized_keys over SSH. The server-side perms matter: chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys. The team that has world-readable .ssh or authorized_keys gets Permission denied (publickey) because sshd refuses insecure permissions on the key files.

FAQ

What is the fastest way to generate a key on Windows?

ssh-keygen -t ed25519 in PowerShell. One command, no GUI, lands in ~/.ssh/. The team that needs a .ppk for PuTTY uses PuTTYgen - that is the only reason to use a GUI tool.

Can I generate multiple keys for different services?

Yes. ssh-keygen -t ed25519 -f ~\.ssh\github_ed25519 creates github_ed25519 and github_ed25519.pub. The team that has one key per service (GitHub, GitLab, personal server) has the right isolation. The team that uses one key everywhere has a single point of compromise.

What if ssh-keygen is not recognized?

Install the OpenSSH client feature. Settings -> Apps -> Optional Features -> OpenSSH Client, or from elevated PowerShell: Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0. The team that has Git for Windows installed already has ssh-keygen - check where ssh-keygen to see which one PATH finds first.

Do I need a different key for GitHub?

You can reuse the same key for GitHub and personal servers. The team that prefers one key per service (github_ed25519, gitlab_ed25519, work-server_ed25519) has better blast-radius control - a compromised GitHub key does not give an attacker your personal server.

How long should my passphrase be?

Four words from a diceware list is the modern recommendation. The team that uses a memorable phrase (correct horse battery staple) has a passphrase that is hard to brute force and easy to type. The team that uses their dog’s name has a passphrase that is one breach away from being compromised.

If you are sizing the infrastructure for the kind of project this post covers, the RunxBuild hosting calculator is the right place to model the line items. The compute, the memory, the storage, the bandwidth, the database - each one is a separate number, and the team’s mental model for the platform is the sum of those numbers. The RunxBuild dashboard is where the team sees the actual usage in one place.

Useful related references:

#ssh#windows#keygen#dev-infra