How to Generate an SSH Key: ssh-keygen, Key Pairs, and Adding Keys to Your Server

If you manage a Linux server and you are still typing a password every time you log in, you are doing it the slow way and the insecure way at the same time. Public-key authentication fixes both problems at once. In this guide we will generate an SSH key with `ssh-keygen`, walk through exactly what a key pair is, push your public key onto a server, lock down file permissions, and finish by turning off password login entirely so brute-force bots have nothing to chew on.

This is a developer-to-developer walkthrough. Every step has a command you can copy, run, and verify. Let’s build the key pair.

Key Takeaways
• An SSH key is a pair: a private key that never leaves your machine and a public key you copy to the server.
• Generate one with `ssh-keygen -t ed25519 -C “your_comment”` — ed25519 is the modern recommended default; RSA 4096 is the compatibility fallback.
• Always set a passphrase on the private key, then use `ssh-agent` so you only type it once per session.
• Add the public key to a server with `ssh-copy-id user@host`, or append it manually to `~/.ssh/authorized_keys`.
Permissions matter: `700` on `~/.ssh`, `600` on private keys, or SSH will refuse to use them.
• Once key login works, disable password authentication to close the door on brute-force attacks.

What is an SSH key pair, and why does it beat passwords?

An SSH key is not a single secret. It is a mathematically linked pair of files:

  • The private key stays on your local machine. It is your identity. You never share it, never paste it anywhere, never commit it to a repo.
  • The public key is the one you copy onto every server you want to access. It is safe to hand out — it can verify a signature but cannot produce one.

The relationship is one-directional: the public key can confirm that you hold the matching private key, but it can never be used to reconstruct that private key. That asymmetry is the whole point. If you want a refresher on the protocol itself, see .

Why bother when passwords already work? A few hard reasons:

Property Password auth SSH key auth
Secret sent to server? Yes, every login No, never
Guessable / brute-forceable Yes No (key space is astronomical)
Phishable Yes Not by transmission
Typing required Every time Once per session (with agent)
Survives a database leak No Yes (server only stores public keys)

Passwords are short enough to be guessed, get reused across services, and travel to the server on every connection. Keys remove all of that.

What actually happens when you authenticate with a key?

Here is the part most tutorials skip, and it is the reason key auth is simultaneously more secure and more convenient.

With a password, the secret travels to the server on every single login. That means it can be intercepted on a compromised network, phished by a fake prompt, or simply brute-forced by a bot hammering port 22. The thing that proves your identity has to leave your machine to do its job — and anything that leaves your machine can be stolen in transit.

SSH key authentication flips that model on its head. Your private key never leaves your computer. When you connect, the server doesn’t ask you to send a secret — it issues a *challenge*. Your local SSH client signs that challenge with your private key and sends back only the signature. The server verifies the signature against the public key it already has on file. At no point does the secret itself travel anywhere.

That is why nothing guessable is ever transmitted, there is nothing to type, and the one secret that matters stays put. The corollary people miss: because your private key *is* your identity, you must protect it like a house key — a strong passphrase plus correct file permissions. And once keys work, turn off password login entirely. Leaving password auth enabled while using keys is like installing a deadbolt and leaving the back door wide open.

How do you generate an SSH key with ssh-keygen?

The command is short. Open a terminal and run:

“`bash ssh-keygen -t ed25519 -C “[email protected]” “`

Breaking that down:

  • `-t ed25519` selects the key type. Ed25519 is fast, modern, and produces small keys with excellent security. Use it unless you have a specific reason not to.
  • `-C “[email protected]”` adds a comment appended to the public key. It is just a label — an email or `user@machine` string helps you identify the key later when a server has several.

If you need to support older systems that don’t understand ed25519, fall back to RSA with a 4096-bit length:

“`bash ssh-keygen -t rsa -b 4096 -C “[email protected]” “`

Here is a quick reference for choosing a key type:

Key type Command flag Notes
Ed25519 `-t ed25519` Recommended default. Small, fast, strong. Supported on all modern systems.
RSA 4096 `-t rsa -b 4096` Compatibility fallback for legacy servers. Larger and slower but universally supported.
ECDSA `-t ecdsa` Works, but ed25519 is generally preferred over it today.
RSA < 2048 Do not use. Considered weak.

What is the passphrase prompt, and should you set one?

Right after you run `ssh-keygen`, you’ll see two prompts:

“`text Generating public/private ed25519 key pair. Enter file in which to save the key (/home/you/.ssh/id_ed25519): Enter passphrase (empty for no passphrase): Enter same passphrase again: “`

The first prompt asks where to save the key — press Enter to accept the default location. The next two ask for a passphrase.

Set a passphrase. Always. The passphrase encrypts your private key file on disk. If your laptop is stolen or your home directory is copied, an attacker still cannot use the key without the passphrase. An unprotected private key is a plaintext credential sitting in a file — exactly the kind of thing you are trying to avoid.

The obvious objection is “but now I have to type something every login, which defeats the convenience.” It does not — that’s what `ssh-agent` is for, and we’ll set it up below so you type the passphrase once per session.

Where are the keys saved after generation?

By default, ed25519 keys land in `~/.ssh/`:

“`text ~/.ssh/id_ed25519 <- private key (KEEP SECRET) ~/.ssh/id_ed25519.pub <- public key (safe to share) ```

For RSA the files are `id_rsa` and `id_rsa.pub`. You can inspect the public key — this is the string you’ll be copying to servers:

“`bash cat ~/.ssh/id_ed25519.pub

“`

Never `cat` your private key into a chat, a ticket, or a screen share. The `.pub` file is the only half that should ever leave your machine.

How do you add the public key to a server?

You have created the key pair; now the server needs your public key in its `~/.ssh/authorized_keys` file. There are two ways.

The easy way: ssh-copy-id

If you can still log in with a password, `ssh-copy-id` does everything for you — it appends your public key and fixes permissions:

“`bash ssh-copy-id -i ~/.ssh/id_ed25519.pub user@your-server-ip “`

Enter your password one last time when prompted. Done. The next login uses the key.

The manual way: append to authorized_keys

When `ssh-copy-id` isn’t available (some minimal systems, or Windows clients), do it by hand. First grab your public key:

“`bash cat ~/.ssh/id_ed25519.pub “`

Then, on the server, create the `.ssh` directory and append the key:

“`bash

mkdir -p ~/.ssh echo “ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI… [email protected]” >> ~/.ssh/authorized_keys “`

Or do it in a single piped command from your local machine:

“`bash cat ~/.ssh/id_ed25519.pub | ssh user@your-server-ip “mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys” “`

If you need a primer on the connection syntax itself, see .

Why do file permissions matter so much?

SSH is deliberately paranoid. If your key files or `.ssh` directory are readable by other users, SSH will silently refuse to use them — this is the single most common reason “my key isn’t working.” Set them correctly on both your local machine and the server:

“`bash chmod 700 ~/.ssh chmod 600 ~/.ssh/id_ed25519 chmod 644 ~/.ssh/id_ed25519.pub chmod 600 ~/.ssh/authorized_keys “`

The rules in plain English:

  • `700` on `~/.ssh` — only you can enter the directory.
  • `600` on private keys and `authorized_keys` — only you can read or write them.
  • `644` on the public key — readable by others is fine, it’s public.

If a login mysteriously falls back to a password prompt, check permissions first and inspect the server log at `/var/log/auth.log` (or run `ssh -v user@host` to see verbose debug output).

How do you test that key login works?

Just connect:

“`bash ssh user@your-server-ip “`

If you set a passphrase, you’ll be asked for it (the passphrase, not the server password). If you reach a shell without a *server password* prompt, key authentication is working. To be certain SSH is using the key and not falling back, run it verbose:

“`bash ssh -v user@your-server-ip “`

Look for a line like `Authentication succeeded (publickey)`. That confirms the key — not a password — got you in.

How do you use ssh-agent so you only type the passphrase once?

Typing the passphrase on every connection is the friction people complain about. `ssh-agent` holds your decrypted key in memory for the session, so you authenticate the passphrase once and every subsequent connection is instant.

Start the agent and add your key:

“`bash eval “$(ssh-agent -s)” ssh-add ~/.ssh/id_ed25519 “`

You’ll be asked for the passphrase one time. From then on, every `ssh` command in that session uses the cached key with no further prompts. To see what the agent is holding:

“`bash ssh-add -l “`

On macOS you can store the passphrase in the Keychain so it loads automatically:

“`bash ssh-add –apple-use-keychain ~/.ssh/id_ed25519 “`

How do you manage multiple keys with ~/.ssh/config?

Once you have keys for several servers — work, personal, a client’s box — `~/.ssh/config` lets you map a friendly name to a host, user, port, and specific key. Create or edit the file:

“`bash

Host myserver HostName 203.0.113.10 User deploy Port 22 IdentityFile ~/.ssh/id_ed25519

Host client-box HostName client.example.com User admin IdentityFile ~/.ssh/id_ed25519_client “`

Now `ssh myserver` connects with the right user, port, and key automatically — no flags to remember. If you run SSH on a non-standard port, the guide covers that side of hardening.

How do you generate an SSH key on Windows?

Modern Windows ships with OpenSSH built in, so the exact same `ssh-keygen` works in PowerShell:

“`powershell ssh-keygen -t ed25519 -C “[email protected]” “`

Keys land in `C:\Users\YourName\.ssh\` (`id_ed25519` and `id_ed25519.pub`). To add the key to a server, use Git Bash for `ssh-copy-id`, or pipe the public key manually:

“`powershell type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh user@your-server-ip “mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys” “`

If you prefer a Unix-like environment, Git Bash gives you `ssh-keygen`, `ssh-copy-id`, and `ssh-agent` exactly as they behave on Linux.


Run your servers on infrastructure that takes SSH seriously. DarazHost VPS and dedicated servers fully support SSH key authentication — generate a key, add it to your server, and log in securely, then disable password auth for maximum protection. It is the secure-by-default access serious server management needs, backed by 24/7 support to help you set it up without locking yourself out of your own box.


How do you disable password authentication for real security?

Generating keys is step one. The security payoff only lands when you turn off password login entirely — otherwise the brute-force bots scanning port 22 still have a target. Once you have confirmed key login works (do not skip that confirmation, or you’ll lock yourself out), edit the SSH daemon config:

“`bash sudo nano /etc/ssh/sshd_config “`

Set these directives:

“`text PasswordAuthentication no PubkeyAuthentication yes ChallengeResponseAuthentication no “`

Then reload the SSH service:

“`bash sudo systemctl restart ssh

sudo systemctl restart sshd “`

From this point, the server only accepts key-based logins. A bot can guess passwords forever and get nowhere, because there is no password to guess. For the full hardening walkthrough — including keeping a backup session open while you test — see .

This is the move that converts “I set up SSH keys” into “my server is actually hardened.” Keys without disabling passwords is a half-finished job.

For the broader context of how SSH key management fits into running production boxes — users, firewalls, services, and updates — see our pillar guide: Linux Server Administration: The Complete Guide to Managing Linux Servers.

Frequently asked questions

Should I use ed25519 or RSA when I generate an SSH key? Use `ed25519` by default — it is faster, produces smaller keys, and offers strong modern security. Only fall back to `rsa -b 4096` if you must connect to a legacy system that doesn’t understand ed25519. Avoid RSA keys smaller than 2048 bits entirely.

Can I use the same SSH key pair on multiple servers? Yes. The public key half is designed to be copied to as many servers as you like; the private key stays on your machine. Many admins use one personal key everywhere. If you want isolation between contexts (work vs. a client), generate a separate key pair per context and map them in `~/.ssh/config`.

What happens if I lose my private key? You lose access to every server that trusts the matching public key — there is no recovery, by design. You’ll need another way in (a console, a second key, or a provider rescue mode) to remove the old public key from `authorized_keys` and add a new one. This is why a passphrase plus a backup access method matters.

Is it safe to share my public key? Yes. The `.pub` file is meant to be shared — that is its entire job. It can verify your signatures but cannot be used to derive your private key or impersonate you. Only the private key (the file *without* `.pub`) must stay secret.

Why does SSH still ask for a password after I added my key? Almost always a permissions or path problem. Confirm `~/.ssh` is `700`, the private key is `600`, and `authorized_keys` on the server is `600`. Run `ssh -v user@host` to see which key SSH tries and why it falls back. If permissions are loose, SSH ignores the key and reverts to password auth.

About the Author

Leave a Reply