Run ssh-keygen -t ed25519 -C "you@example.com", press Enter to accept the default file location, and type a passphrase when asked. This creates two files: the private key id_ed25519, which never leaves your computer, and the public key id_ed25519.pub, which you copy to servers and services such as GitHub.
The same command works in PowerShell and Command Prompt on Windows 10 and 11 (OpenSSH is built in), in Terminal on macOS, and in any Linux shell.
How to create the key
ssh-keygen -t ed25519 -C "you@example.com"
-t ed25519 picks the key type. Current OpenSSH already defaults to Ed25519, but naming it explicitly gives you the same result on older versions that default to RSA. -C sets a comment: a label at the end of the public key that helps you recognise it later. Your email or name@laptop both work.
You are then asked three questions. The prompts look like this (Windows shown; the default path differs per OS):
Generating public/private ed25519 key pair.
Enter file in which to save the key (C:\Users\alex/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Press Enter at the first prompt to use the default location. If a key with that name already exists, ssh-keygen asks whether to overwrite it: answer n unless you are sure the old key is no longer used anywhere, and give the new key a different file name instead.
When it finishes, it prints where the files went and the key's fingerprint. Real output from OpenSSH_for_Windows_9.5p1 on Windows 11:
Your identification has been saved in C:\Users\alex/.ssh/id_ed25519
Your public key has been saved in C:\Users\alex/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:FL1Dve3XbYClI59maKsK//PpOMXWpB4AlHMtXG9jPks you@example.com
It also prints a "randomart" picture, which is a visual version of the same fingerprint and can be ignored.
Where the key files are stored
| OS | Private key | Public key |
|---|---|---|
| Windows | C:\Users\you\.ssh\id_ed25519 | C:\Users\you\.ssh\id_ed25519.pub |
| macOS | /Users/you/.ssh/id_ed25519 | /Users/you/.ssh/id_ed25519.pub |
| Linux | /home/you/.ssh/id_ed25519 | /home/you/.ssh/id_ed25519.pub |
The two files are small: on our Windows test the private key was 411 bytes and the public key 98 bytes. The public key is a single line that looks like this:
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJS7Tyyz1WS9Q6K5m4EElRkqYlahAQ7NVwz/z11755Nz you@example.com
The OpenSSH manual says the private key file "should not be readable by anyone but the user", while for the public key "there is no need to keep the contents of this file secret". The ssh manual adds that it "will simply ignore a private key file if it is accessible by others". On macOS and Linux, fix that with chmod 600 ~/.ssh/id_ed25519 (see Linux file permissions explained for what 600 means).
Should you set a passphrase?
Yes, for a key you use interactively. Without one, anyone who copies the private key file can log in as you. With one, the file is encrypted and useless without the passphrase. Microsoft's OpenSSH documentation says it does not recommend an empty passphrase for the same reason. The usual objection, typing it on every connection, goes away once the key is loaded into ssh-agent, which asks once per session.
Leave the passphrase empty only for keys used by unattended scripts, and limit what those keys can do on the server.
To add or change a passphrase on an existing key:
ssh-keygen -p -f ~/.ssh/id_ed25519
How to add the key to ssh-agent on Windows
Windows includes an ssh-agent service, but it is disabled by default. On a fresh Windows 11 install, Get-Service ssh-agent reports status Stopped and start type Disabled, and ssh-add fails with:
Error connecting to agent: No such file or directory
Enable and start it from PowerShell running as administrator:
Get-Service ssh-agent | Set-Service -StartupType Automatic
Start-Service ssh-agent
(GitHub's instructions use -StartupType Manual, which also works, but then you have to run Start-Service ssh-agent after each restart.) Then, in a normal PowerShell window, add the key:
ssh-add $env:USERPROFILE\.ssh\id_ed25519
You type the passphrase once. Microsoft describes the Windows agent as storing the key within a security context associated with your Windows account, and the agent then supplies it to ssh for you.
How to add the key to ssh-agent on macOS (with Keychain)
macOS runs an agent for you. To store the passphrase in your Keychain so you are not asked again, add the key with Apple's extra flag:
ssh-add --apple-use-keychain ~/.ssh/id_ed25519
Then create or edit ~/.ssh/config so the key is loaded automatically. GitHub documents this block:
Host github.com
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/id_ed25519
Use Host * instead of Host github.com to apply it to every server. UseKeychain exists only in Apple's build of OpenSSH, so leave it out of config files you copy to Linux.
How to add the key to ssh-agent on Linux
Most desktop Linux sessions already start an agent. If ssh-add -l says it cannot connect to the agent, start one in the current shell, then add the key:
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
An agent started this way lasts only as long as that terminal session.
How to copy the public key to a server
On macOS and Linux, ssh-copy-id logs in with your password once and appends the key to the server's ~/.ssh/authorized_keys, creating the file and folder if needed:
ssh-copy-id -i ~/.ssh/id_ed25519.pub alex@server.example.com
-i makes sure only that key is installed. Windows' built-in OpenSSH does not include ssh-copy-id (the C:\Windows\System32\OpenSSH folder has ssh, scp, sftp, ssh-add, ssh-agent, ssh-keygen and ssh-keyscan), but Git Bash ships it. From plain PowerShell, pipe the key to a Linux server yourself:
Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub | ssh alex@server.example.com "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
For a Windows server running OpenSSH Server, the file location depends on the account: standard users use C:\Users\username\.ssh\authorized_keys, while members of the Administrators group must use C:\ProgramData\ssh\administrators_authorized_keys, with permissions limited to Administrators and SYSTEM. Microsoft's key-management page has the exact commands.
Then test it. You should be logged in without a password prompt (you may be asked for the key's passphrase if it is not in the agent):
ssh alex@server.example.com
How to add the key to GitHub
Print the public key and copy the whole line:
cat ~/.ssh/id_ed25519.pub
(In PowerShell, Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub | Set-Clipboard copies it directly; on macOS, pbcopy < ~/.ssh/id_ed25519.pub.) On GitHub, click your profile picture, then Settings > SSH and GPG keys > New SSH key. Give it a title, leave the key type as Authentication Key, paste the key, and click Add SSH key. Then check the connection:
ssh -T git@github.com
On success GitHub replies: Hi USERNAME! You've successfully authenticated, but GitHub does not provide shell access. The first time, ssh also asks you to confirm GitHub's host key fingerprint; compare it with the fingerprints GitHub publishes before typing yes.
Never paste the file without .pub. That is your private key, and anyone who has it can sign in as you.
If it still asks for a password
- Check the key the server sees:
ssh -v alex@server.example.comprints which key files it offers and whether the server accepted them. - On a Linux server,
sshdchecks the file modes and ownership of your home folder and key files before accepting a login (theStrictModessetting, on by default), and refuses keys in files or folders that other users can write to.chmod 700 ~/.sshandchmod 600 ~/.ssh/authorized_keysfix the usual case. - Make sure the public key went in as one unbroken line. Copying from a terminal window sometimes inserts line breaks.
- Compare fingerprints:
ssh-keygen -l -f ~/.ssh/id_ed25519.pubon your computer should match the key listed on the server or in GitHub's settings.
Frequently asked questions
- Should I use Ed25519 or RSA?
- Use Ed25519 unless a system you need to connect to doesn't accept it. Current OpenSSH makes Ed25519 the default key type, and GitHub's instructions use it. Some older servers and network devices only accept RSA; for those, generate a separate RSA key with ssh-keygen -t rsa -b 4096.
- Can I add or change the passphrase later?
- Yes. Run ssh-keygen -p -f ~/.ssh/id_ed25519. It asks for the old passphrase (press Enter if there was none) and then the new one. The key itself does not change, so you don't need to update servers or GitHub.
- I lost my private key. Can I recover it from the public key?
- No. The public key cannot be turned back into the private key; that is the point of the design. Generate a new key pair, add the new public key everywhere you used the old one, and remove the old public key from those servers and accounts.
- Can I use the same key on several computers?
- You can copy the private key, but a separate key per computer is safer. If one machine is lost or compromised, you remove just that machine's public key from your servers and accounts, and the others keep working.
- What does the -C comment do?
- It is a label stored at the end of the public key line, usually your email or user@host. It helps you recognise the key in an authorized_keys file or your GitHub settings. It has no effect on security, and you can change it later with ssh-keygen -c.
Sources
- OpenBSD manual — ssh-keygen(1)
- OpenBSD manual — ssh(1)
- OpenBSD manual — sshd_config(5)
- GitHub Docs — Adding a new SSH key to your GitHub account
- Linux man-pages — ssh-copy-id(1)
- GitHub Docs — Generating a new SSH key and adding it to the ssh-agent
- GitHub Docs — Testing your SSH connection
- Microsoft Learn — Key-based authentication in OpenSSH for Windows