Updated: 12 October 2026 · Applies to: OpenSSH 9.6p1 (Ubuntu 24.04), 9.9p1 (AlmaLinux 10.2), 10.0p1 (Debian 13) and 10.2p1 (Ubuntu 26.04); PuTTYgen 0.81 and 0.83 (putty-tools)
To generate an SSH key in Linux, run ssh-keygen -t ed25519 -C "admin@laptop" on your own computer, press Enter to accept the file ~/.ssh/id_ed25519 and type a passphrase. You get two files: the private key id_ed25519, which stays with you, and the public key id_ed25519.pub, which goes on the server. If a tool or panel asks for a PEM key file instead, create an RSA key in PEM format:
ssh-keygen -t ed25519 -C "admin@laptop" # normal SSH key ssh-keygen -t rsa -b 4096 -m PEM -f ~/.ssh/server-key.pem # PEM key file
Putting the public key on a server and turning off password logins is in how to set up SSH keys for authentication; on Windows, see create SSH keys on Windows. All output below is lab output from test containers, with fingerprints and keys replaced by placeholders.
Generate an SSH key pair step by step
- Open a terminal on the computer you connect from, not on the server, so the private key never has to travel.
- Run ssh-keygen.
-tsets the key type and-Cadds a label (without it, the label isuser@hostname):ssh-keygen -t ed25519 -C "admin@laptop"
Since OpenSSH 9.5, Ed25519 is the default type, so plainssh-keygengave an Ed25519 key on all four test systems. - Accept the file name by pressing Enter. ssh-keygen creates
~/.sshif it does not exist yet. - Type a passphrase twice. It encrypts the private key, so a stolen copy is useless without it. Leave it empty only for script keys. Lab output (Debian 13, shortened):
$ ssh-keygen -t ed25519 -C "admin@laptop" Generating public/private ed25519 key pair. Enter file in which to save the key (/home/admin/.ssh/id_ed25519): Created directory '/home/admin/.ssh'. Enter passphrase for "/home/admin/.ssh/id_ed25519" (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/admin/.ssh/id_ed25519 Your public key has been saved in /home/admin/.ssh/id_ed25519.pub The key fingerprint is: SHA256:(your key fingerprint) admin@laptop (randomart image left out)
On Ubuntu 24.04 (OpenSSH 9.6) the prompt is shorter:Enter passphrase (empty for no passphrase):. - Check the two files. The private key must be readable only by you (
-rw-------):$ ls -l ~/.ssh -rw------- 1 admin admin 444 Oct 11 16:02 id_ed25519 -rw-r--r-- 1 admin admin 94 Oct 11 16:02 id_ed25519.pub $ cat ~/.ssh/id_ed25519.pub ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA...(shortened) admin@laptop
Ed25519 or RSA? Use Ed25519 for current servers: the keys are short and OpenSSH has supported them since version 6.5. Use RSA when a system only accepts RSA or when you need a PEM file. ssh-keygen makes 3072-bit RSA keys by default, which its manual calls sufficient; -b 4096 gives a larger one.
What is a PEM key?
PEM is a text format: Base64 data between a -----BEGIN ...----- and an -----END ...----- line. SSL certificates use the same wrapping. For SSH, a "PEM key" or .pem file usually means a private key in the older OpenSSL format, which some cloud platforms, panels and older tools hand out or expect. The extension means nothing; the first line tells you what you have:
-----BEGIN OPENSSH PRIVATE KEY-----: OpenSSH's own format, the ssh-keygen default since OpenSSH 7.8.-----BEGIN RSA PRIVATE KEY-----: a classic PEM RSA key. If the second line isProc-Type: 4,ENCRYPTED, it has a passphrase.-----BEGIN EC PRIVATE KEY-----: a PEM ECDSA key.-----BEGIN PRIVATE KEY-----: PKCS#8, for example fromopenssl genpkey.PuTTY-User-Key-File-3:: a PuTTY PPK key, not PEM. Convert it first (see below).
In our lab, ssh -i logged in with all three PEM types: from ssh-keygen, from OpenSSL and converted by PuTTYgen.
Generate a PEM key file
ssh-keygen -t rsa -b 4096 -m PEM -C "admin@laptop" -f ~/.ssh/server-key.pem
-m PEM writes the legacy PEM format and -f sets the file name. The public key is saved next to it as server-key.pem.pub. Lab output (Debian 13):
$ ls -l ~/.ssh -rw------- 1 admin admin 3243 Oct 11 16:02 server-key.pem -rw-r--r-- 1 admin admin 738 Oct 11 16:02 server-key.pem.pub $ head -1 ~/.ssh/server-key.pem -----BEGIN RSA PRIVATE KEY-----
Use PEM only when something needs it. According to the OpenSSH release notes, the default OpenSSH format resists offline passphrase guessing much better and keeps the key comment. Note that Ed25519 keys cannot be stored as PEM: ssh-keygen -t ed25519 -m PEM still wrote BEGIN OPENSSH PRIVATE KEY on every system we tested, without a warning. ECDSA works (-t ecdsa -m PEM gives BEGIN EC PRIVATE KEY).
Convert an existing key to or from PEM
ssh-keygen -p rewrites the private key in place, so make a copy first. It asks for the current passphrase and then the new one; type the same one to keep it.
cp ~/.ssh/id_rsa ~/.ssh/id_rsa.bak ssh-keygen -p -m PEM -f ~/.ssh/id_rsa # OpenSSH format to PEM ssh-keygen -p -f ~/.ssh/server-key.pem # PEM back to OpenSSH format ssh-keygen -p -m PKCS8 -f ~/.ssh/id_rsa # PKCS#8 (BEGIN PRIVATE KEY) ssh-keygen -y -f ~/.ssh/server-key.pem > ~/.ssh/server-key.pub # public key from a .pem
The last line rebuilds the public key when you were only given a .pem file.
Convert a PPK key to PEM, or PEM to PPK
On Debian and Ubuntu, install putty-tools for the command-line puttygen:
sudo apt install putty-tools puttygen mykey.ppk -O private-openssh -o mykey.pem # PPK to PEM puttygen server-key.pem -o server-key.ppk # PEM to PPK
If the PPK has a passphrase, puttygen asks for it (Enter passphrase to load key:) and the PEM file keeps the same passphrase. An RSA PPK becomes BEGIN RSA PRIVATE KEY; an Ed25519 PPK comes out in OpenSSH format. In the Windows PuTTYgen, according to the PuTTY manual: Load the .ppk, then Conversions > Export OpenSSH key; for PEM to PPK, load the .pem and click Save private key. PuTTYgen saves PPK version 3; choose version 2 only for PuTTY 0.74 and older or a tool that cannot read version 3. Connecting with PuTTY itself is covered in how to access your server or VPS using PuTTY.
Log in with a PEM key
- Lock down the file. OpenSSH ignores a private key that other users can read:
chmod 600 ~/.ssh/server-key.pem
Without it you get this (lab output, shortened: test options and the known_hosts line left out, address replaced):$ ssh -i server-key.pem admin@203.0.113.10 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: UNPROTECTED PRIVATE KEY FILE! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Permissions 0644 for 'server-key.pem' are too open. It is required that your private key files are NOT accessible by others. This private key will be ignored. Load key "server-key.pem": bad permissions admin@203.0.113.10: Permission denied (publickey).
- Put the public key on the server if it is not there yet.
ssh-copy-idlogs in with your password once and adds the key (lab output, shortened):$ ssh-copy-id -i ~/.ssh/server-key.pem.pub admin@203.0.113.10 ... Number of key(s) added: 1
Doing it by hand: set up SSH keys for authentication. On a cPanel server you can also create and authorise root keys in WHM: see server access by key (pem or ppk) via WHM. - Connect with the key:
ssh -i ~/.ssh/server-key.pem admin@203.0.113.10
- Save typing (optional). Add a block to
~/.ssh/config, then connect withssh myserver:Host myserver HostName 203.0.113.10 User admin IdentityFile ~/.ssh/server-key.pem IdentitiesOnly yes
Common errors
Load key "server-key.pem": bad permissions: runchmod 600on the key.Load key "mykey.ppk": error in libcrypto(Debian 13, Ubuntu 24.04 and 26.04) orinvalid format(AlmaLinux 10): you passed a PuTTY key to OpenSSH. Convert it to PEM with puttygen.Warning: Identity file ... not accessible: No such file or directory.: the path after-iis wrong.Permission denied (publickey)with a correct key file: the matching public key is not in~/.ssh/authorized_keysof that user on the server. See how to fix SSH permission denied.
Keep the private key safe: never email it or paste it into chat, and back it up privately. If you created the pair on the server, copy the private key to your computer and delete it there. The public key is safe to share.
Official documentation: ssh-keygen manual, OpenSSH release notes and PuTTY documentation.