TL;DR:
- To generate an SSH key, run
ssh-keygen -t ed25519 -C "YOUR_EMAIL"in PowerShell on Windows 11 or in Terminal on macOS and Linux. The command is the same on all three. - The private key saves to
~/.ssh/id_ed25519and the public key to~/.ssh/id_ed25519.pub. Only the.publine goes on a server. - Ed25519 has been the
ssh-keygendefault since OpenSSH 9.5 (October 2023). Use-t rsa -b 4096only for systems that cannot read Ed25519 keys. - Copy the key with
ssh-copy-idon macOS and Linux. Windows OpenSSH has nossh-copy-id, so pipe the file throughsshin PowerShell. - On the server, set
~/.sshto mode700andauthorized_keysto600. sshd ignores keys in files that other users can modify. - PuTTY reads only
.ppkkey files: create one in PuTTYgen 0.85 with the EdDSA (Ed25519) type, or import an existing OpenSSH key.
Applies to: Windows 11 (OpenSSH Client) · macOS 26.6 (OpenSSH 10.3) · Ubuntu 24.04 LTS and 26.04 LTS (OpenSSH 9.6 and 10.2) · PuTTY 0.85 · checked October 2026
An SSH key is a pair of files that proves your identity to a server without a password: a private key that stays on your computer and a public key that you place on the server. This tutorial generates an Ed25519 key with ssh-keygen on Windows 11, macOS, and Linux, creates a PuTTY key with PuTTYgen, copies the public key to a Linux server, and sets up ssh-agent, a host alias, and key-only login. The same public key also works for GitHub and GitLab.
Prerequisites
- A computer running Windows 10 (build 1809 or later) or Windows 11, macOS, or a Linux distribution such as Ubuntu.
- A Linux server you can reach over SSH, and its IP address. What Is a VPS? explains how a virtual server works and what you can run on one.
- Password login on the server for the copy step, unless you add the key when you deploy the server (Step 3, Option A).
Run commands in PowerShell on Windows and in Terminal on macOS and Linux. Replace values written in capitals, such as YOUR_USER and YOUR_SERVER_IP, with your own. Examples use the documentation address 203.0.113.10 and the user deploy.
Ed25519 or RSA: which key type to use
Use Ed25519. It is an elliptic-curve signature algorithm designed for about the 128-bit security level (RFC 8032), and Ubuntu's server documentation recommends it for its shorter keys and lower computing cost. RSA is the fallback for systems older than OpenSSH 6.5, the January 2014 release that added Ed25519. OpenSSH 10.0 removed DSA keys in April 2025.
| Ed25519 | RSA 4096 | |
|---|---|---|
| Command | ssh-keygen -t ed25519 | ssh-keygen -t rsa -b 4096 |
| Key size | 256 bits, fixed | 4,096 bits (the RSA default is 3,072) |
| Public key line | About 80 characters | About 725 characters |
| Default files | id_ed25519, id_ed25519.pub | id_rsa, id_rsa.pub |
| Use it for | Servers, GitHub, GitLab | Older systems and network devices without Ed25519 |
Step 1: Generate an SSH key with ssh-keygen (Ed25519)
ssh-keygen creates the key pair and asks for a file name and a passphrase. Set a passphrase: it encrypts the private key file, and Step 5 loads the key into ssh-agent so you type the passphrase once per session.
Generate an SSH key on Windows 11
Open PowerShell or Windows Terminal from the Start menu and run:
ssh-keygen -t ed25519 -C "YOUR_EMAIL"
Replace YOUR_EMAIL with an email address or a device name. The comment labels the key inside authorized_keys. Press Enter to accept the default path, C:\Users\YOUR_USER\.ssh\id_ed25519, then type the passphrase twice.
If PowerShell reports that ssh-keygen is not recognized, install the OpenSSH Client in a PowerShell window opened as Administrator:
Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0
Generate an SSH key on Mac
Open Terminal from Applications > Utilities and run the same command. macOS 26.6 includes OpenSSH 10.3 in /usr/bin.
ssh-keygen -t ed25519 -C "YOUR_EMAIL"
The output looks similar to this:
Generating public/private ed25519 key pair.
Enter file in which to save the key (/Users/you/.ssh/id_ed25519):
Enter passphrase for "/Users/you/.ssh/id_ed25519" (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/you/.ssh/id_ed25519
Your public key has been saved in /Users/you/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:D75239AXO1Gtc7SngrpBpBQTUo5hsqn7T4sTmjd/3Do you@laptop
...
Generate an Ed25519 SSH key on Linux and Ubuntu
Ubuntu includes ssh-keygen in the openssh-client package. Run the same command in a terminal:
ssh-keygen -t ed25519 -C "YOUR_EMAIL"
On Ubuntu 24.04 (OpenSSH 9.6) the passphrase prompt reads Enter passphrase (empty for no passphrase):. The rest matches the macOS output. If the command is missing, install it with sudo apt install openssh-client.
Print the public key on macOS or Linux:
cat ~/.ssh/id_ed25519.pub
On Windows, run Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub. The output is one line:
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINmprYolhLeHj3lSMK+FD7iItCaKm1HqdM6M8mOTGT3q you@laptop
Step 2: Create a PuTTY key with PuTTYgen (optional)
PuTTY stores private keys in its own .ppk format and cannot load OpenSSH private keys. PuTTYgen installs with PuTTY; the current release is 0.85, from August 2026.
- Open PuTTYgen and select EdDSA as the key type. Ed25519 is its 255-bit option.
- Click Generate and move the mouse over the blank area until the progress bar fills.
- Type a passphrase in Key passphrase and Confirm passphrase, then click Save private key.
- Copy the line in the Public key for pasting into OpenSSH authorized_keys file box. It goes on the server in Step 3.
- In PuTTY, go to Connection > SSH > Auth > Credentials and select the
.ppkfile under Private key file for authentication.
To use a key from Step 1 in PuTTY, open Conversions > Import key, select id_ed25519, and click Save private key. Conversions > Export OpenSSH key converts in the other direction.
Step 3: Add the SSH key to your VPS
sshd reads public keys from ~/.ssh/authorized_keys in the home folder of the account you log in as. Pick one option. Options B to D log in with a password. OpenSSH's default setting, PermitRootLogin prohibit-password, refuses passwords for root, so use Option A if the server rejects the root password.
Option A: Add the key when you deploy the server
Arct Cloud Linux VPS images accept an SSH public key at deploy. Paste the full line from id_ed25519.pub when you create the server, then go to Step 4.
Option B: Use ssh-copy-id on macOS and Linux
ssh-copy-id -i ~/.ssh/id_ed25519.pub YOUR_USER@YOUR_SERVER_IP
For YOUR_USER, use the account the server gave you, such as root; Step 4 creates the deploy user. Type that account's password when asked. ssh-copy-id creates ~/.ssh and authorized_keys on the server if they are missing and appends the key. The output includes lines similar to these:
...
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
[email protected]'s password:
Number of key(s) added: 1
...
Option C: Pipe the key through ssh on Windows
Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub | ssh YOUR_USER@YOUR_SERVER_IP "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
The command logs in once with the password, appends the key, and sets both permissions.
Option D: Add the key by hand
Log in to the server with the password, then create the folder and open the file:
mkdir -p ~/.ssh
chmod 700 ~/.ssh
nano ~/.ssh/authorized_keys
Paste the public key on its own line, save with Ctrl+O, and exit with Ctrl+X. Then restrict the file, because sshd's StrictModes check rejects keys that other users can modify:
chmod 600 ~/.ssh/authorized_keys
Step 4: Log in and check the host key
Connect with the key as the account that holds it: root on servers that provide root SSH, or the user your provider created.
ssh YOUR_USER@YOUR_SERVER_IP
On the first connection, ssh shows the server's host key. The output looks similar to this:
The authenticity of host '203.0.113.10 (203.0.113.10)' can't be established.
ED25519 key fingerprint is: SHA256:ASyydV6c6l4A0YWOBt+4HHfBAh8E0OYb5hLOWB2lqbU
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])?
OpenSSH 9.x and older clients, such as the one in Ubuntu 24.04, print ED25519 key fingerprint is SHA256:... without the colon and end the line with a period.
The host key is the server's own key pair, stored in /etc/ssh. If you can read its fingerprint through another trusted channel, compare it, then type yes. ssh saves it in ~/.ssh/known_hosts, warns if it changes later, asks for your key passphrase, and opens a shell without the server password. On the server, ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub prints the fingerprint.
Give a sudo user the same key
If you logged in as root, create a non-root user with sudo privileges and copy your key to it:
sudo adduser deploy
sudo usermod -aG sudo deploy
sudo install -d -m 700 -o deploy -g deploy /home/deploy/.ssh
sudo install -m 600 -o deploy -g deploy ~/.ssh/authorized_keys /home/deploy/.ssh/authorized_keys
adduser asks for a password, which sudo uses. Log in as deploy from now on.
Step 5: Load the key into ssh-agent
ssh-agent holds the decrypted key in memory, so ssh stops asking for the passphrase at each login.
Windows 11
The ssh-agent service is disabled by default. Enable and start it in a PowerShell window opened as Administrator:
Get-Service ssh-agent | Set-Service -StartupType Automatic
Start-Service ssh-agent
Then add the key:
ssh-add $env:USERPROFILE\.ssh\id_ed25519
macOS
Create ~/.ssh/config with touch ~/.ssh/config if it does not exist, and add these lines:
Host *
IgnoreUnknown UseKeychain
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/id_ed25519
UseKeychain is a macOS option that some ssh builds lack, such as Homebrew's. The IgnoreUnknown line above it stops those builds from failing with Bad configuration option: usekeychain.
Then store the passphrase in the macOS keychain:
ssh-add --apple-use-keychain ~/.ssh/id_ed25519
Linux
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
The output looks similar to this:
Identity added: /home/you/.ssh/id_ed25519 (you@laptop)
Step 6: Add a host alias in ~/.ssh/config
A Host block stores the address, user, and key under a short name. Add it above any Host * block in ~/.ssh/config on macOS and Linux, or in C:\Users\YOUR_USER\.ssh\config on Windows (saved without a .txt extension):
Host myvps
HostName YOUR_SERVER_IP
User deploy
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
Connect with ssh myvps. ssh uses the first value it finds for each setting, which is why specific blocks go above Host *. IdentitiesOnly yes makes ssh offer only this key, which prevents Too many authentication failures when the agent holds several keys.
Step 7: Turn off password login and test it
With key login working, turn off password login so the server stops accepting password guesses. Keep your current session open until a new terminal logs in with the key after the restart.
sudo tee /etc/ssh/sshd_config.d/10-key-only.conf > /dev/null <<'EOF'
PasswordAuthentication no
KbdInteractiveAuthentication no
EOF
Ubuntu loads sshd_config.d/*.conf in name order before the rest of sshd_config, and sshd keeps the first value it reads, so the 10- prefix wins over later snippets. Check the syntax (no output means valid) and restart the service, named ssh on Ubuntu 24.04 and 26.04:
sudo sshd -t
sudo systemctl restart ssh
Confirm the active settings:
sudo sshd -T | grep -Ei '^(pubkeyauthentication|passwordauthentication|kbdinteractiveauthentication) '
The output looks similar to this:
pubkeyauthentication yes
passwordauthentication no
kbdinteractiveauthentication no
From your computer, try a password login on purpose:
ssh -o PubkeyAuthentication=no -o PreferredAuthentications=password YOUR_USER@YOUR_SERVER_IP
The server refuses it:
[email protected]: Permission denied (publickey).
Block root logins (optional)
Once ssh myvps logs in as deploy and sudo works there, you can refuse SSH logins for root as well. Keep the current session open until a new ssh myvps login works after the restart.
echo 'PermitRootLogin no' | sudo tee -a /etc/ssh/sshd_config.d/10-key-only.conf
sudo sshd -t
sudo systemctl restart ssh
A login as root then fails with Permission denied (publickey).
Troubleshoot common SSH key errors
Run ssh -v YOUR_USER@YOUR_SERVER_IP to see which keys the client offers. On the server, sudo journalctl -u ssh shows why sshd rejected a key.
| Symptom | Cause | Fix |
|---|---|---|
Permission denied (publickey). | The key is missing from that user's authorized_keys, or ssh offered a different key | Check the user name, add -i ~/.ssh/id_ed25519, or set IdentityFile and IdentitiesOnly yes |
WARNING: UNPROTECTED PRIVATE KEY FILE! and Permissions 0644 ... are too open. | Other users can read the private key | chmod 600 ~/.ssh/id_ed25519 on macOS and Linux. On Windows: icacls $env:USERPROFILE\.ssh\id_ed25519 /inheritance:r /grant:r "$($env:USERNAME):F" |
Authentication refused: bad ownership or modes for directory /home/deploy/.ssh in the server log | StrictModes found a writable folder or file | chmod 700 ~/.ssh and chmod 600 ~/.ssh/authorized_keys as that user |
WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! | The server was rebuilt at the same IP address, or the connection is intercepted | Confirm the rebuild, then run ssh-keygen -R YOUR_SERVER_IP |
Could not open a connection to your authentication agent. (Windows: Error connecting to agent: No such file or directory) | No agent runs in this shell, or the Windows ssh-agent service is stopped | eval "$(ssh-agent -s)", then ssh-add. On Windows, start the ssh-agent service (Step 5) |
PuTTY shows Unable to use key file | PuTTY was given an OpenSSH private key | Import it in PuTTYgen and save a .ppk file |
FAQ
Is ed25519 better than RSA?
Yes, for SSH logins. Ed25519 keys are shorter, need less computing power, and have been the ssh-keygen default since OpenSSH 9.5. Choose RSA 4096 only when a device or an old server cannot read Ed25519 keys.
How do I generate ~/.ssh/id_ed25519?
Run ssh-keygen -t ed25519 and press Enter at the file prompt. ssh-keygen writes the private key to ~/.ssh/id_ed25519 and the public key to ~/.ssh/id_ed25519.pub, and creates the .ssh folder if it is missing.
What is an SSH host key?
An SSH host key is the server's own key pair, stored in /etc/ssh, that proves the server's identity. Your client saves its fingerprint in ~/.ssh/known_hosts on the first login and warns you if the key changes later.
How do I generate an SSH key with PuTTY?
Open PuTTYgen, select EdDSA, click Generate, and move the mouse until the bar fills. Set a passphrase, save the private key as a .ppk file, and copy the one-line public key from the box at the top into the server's authorized_keys file.
Can I generate an SSH key online?
You can, but the private key then exists on a website's systems before it reaches you. ssh-keygen and PuTTYgen create the key on your own computer, and only the public key needs to leave it.
Can I use the same SSH key for GitHub and my server?
Yes. One public key can sit on any number of servers and on GitHub at the same time. Separate keys per purpose limit what one lost key exposes; set IdentityFile in ~/.ssh/config to pick the key for each host.
Next steps
- Install Docker and Docker Compose on Ubuntu
- Upgrade Ubuntu 24.04 to 26.04 LTS on a VPS
- Secure RDP on Windows Server, for servers you manage over Remote Desktop
- OpenSSH manual pages
Arct Cloud Linux images deploy in under 30 seconds with root SSH on every plan. Compare plans.
This work is licensed under CC BY-NC-SA 4.0.