Understanding SSH-keygen
ssh-keygen is an OpenSSH utility for generating and managing cryptographic keys used by SSH. It is foundational for secure server access because it enables key-based authentication, which is stronger and more operationally reliable than password-based SSH when deployed correctly.
Key-based authentication is widely used in production because:
- Keys are resistant to brute-force attacks (unlike passwords)
- Keys can be scoped, rotated, and organized per environment
- Keys integrate cleanly with automation (CI/CD, provisioning, configuration management)
- Keys can be protected with passphrases and loaded with
ssh-agent
Focus: practical understanding of ssh-keygen for creating, inspecting, rotating, converting, and troubleshooting SSH keys on modern Linux/macOS/WSL environments.
The private key must remain secret. Treat it like a password with higher impact. Anyone who obtains the private key can authenticate as you (especially if the key has no passphrase).
Key Pair Basics
A standard SSH key pair has two files:
| File | Purpose | Example |
|---|---|---|
| Private key | Secret credential; never share | ~/.ssh/id_ed25519 |
| Public key | Installed on servers/services | ~/.ssh/id_ed25519.pub |
Where keys are used
- Server access: public key placed in
~/.ssh/authorized_keys - Git hosting: public key uploaded to GitHub/GitLab/Bitbucket
- Automation: keys used by CI/CD runners or deployment agents
Recommended Key Types
Modern OpenSSH best default:
ed25519(fast, compact, strong, and widely supported)
Compatibility option:
rsawith4096bits (for older systems or strict compatibility requirements)
Avoid:
dsa(insecure/deprecated)ecdsa(generally not preferred whened25519is available)
Use ed25519 for new keys unless you must support a legacy system that does not accept it.
Basic Syntax
ssh-keygen [options]
Running with no options starts an interactive wizard:
ssh-keygen
Typical interactive prompts:
- File to save the key
- Passphrase (optional but recommended)
Generate Keys (Common Patterns)
Generate an ED25519 key (recommended)
ssh-keygen -t ed25519
Generate ED25519 with comment (helps identify keys)
ssh-keygen -t ed25519 -C "you@example.com"
Generate with custom filename (recommended for multiple servers)
ssh-keygen -t ed25519 -f ~/.ssh/wpserver_key -C "wpserver"
Generate RSA 4096 (compatibility)
ssh-keygen -t rsa -b 4096 -C "you@example.com"
A passphrase encrypts your private key at rest. Without a passphrase, anyone with the key file can use it immediately.
Core Options and Flags
The table below covers commonly used and security-relevant flags.
| Flag | Purpose | Example | Notes |
|---|---|---|---|
| - | -- | - | -- |
-t | Key type | ssh-keygen -t ed25519 | ed25519 recommended |
-b | Key size (bits) | ssh-keygen -t rsa -b 4096 | Relevant for RSA; ignored by ED25519 |
-C | Comment label | ssh-keygen -C "deploy@prod" | Stored in public key line for identification |
-f | Output file path | ssh-keygen -f ~/.ssh/prod_key | Avoid overwriting defaults when managing many keys |
-N | Passphrase (non-interactive) | ssh-keygen -N "pass" -f ~/.ssh/key | Useful for automation; treat carefully |
-q | Quiet mode | ssh-keygen -q -t ed25519 -f ~/.ssh/key | Useful for scripts |
-p | Change passphrase | ssh-keygen -p -f ~/.ssh/id_ed25519 | Rotate passphrase without changing key material |
-y | Extract public key from private | ssh-keygen -y -f ~/.ssh/id_ed25519 | Useful if .pub is missing |
-l | Show fingerprint | ssh-keygen -l -f ~/.ssh/id_ed25519.pub | Identifies a key uniquely |
-E | Fingerprint hash format | ssh-keygen -l -E sha256 -f key.pub | SHA256 default; MD5 supported |
-R | Remove host from known_hosts | ssh-keygen -R example.com | Fix host key mismatch after rebuild |
-F | Find host in known_hosts | ssh-keygen -F example.com | Search known_hosts entries |
-A | Generate missing host keys | sudo ssh-keygen -A | For SSH server host keys (not user keys) |
-k | Create Key Revocation List (KRL) | ssh-keygen -k -f revoked.krl bad.pub | Admin use; advanced access control |
Interactive Prompts (What They Mean)
When generating a key, typical output:
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/user/.ssh/id_ed25519):
- Press
Enterto accept default path - Or provide a custom key name (recommended per-server/per-purpose)
Passphrase prompt:
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
- A passphrase protects the private key at rest
- If the passphrase is lost, the private key cannot be used
Inspect and Verify Keys
Show public key contents
cat ~/.ssh/id_ed25519.pub
Show fingerprint (most common audit command)
ssh-keygen -lf ~/.ssh/id_ed25519.pub
Example output:
256 SHA256:abcdEFghijk... you@example.com (ED25519)
Show fingerprint using a specific hash format
ssh-keygen -lf -E sha256 ~/.ssh/id_ed25519.pub
MD5 (legacy display; not recommended for new workflows):
ssh-keygen -lf -E md5 ~/.ssh/id_ed25519.pub
Confirm file permissions (important)
ls -l ~/.ssh/id_ed25519*
Recommended:
-rw- id_ed25519
-rw-r--r-- id_ed25519.pub
Recover a Missing Public Key
If the .pub file is deleted but the private key still exists:
ssh-keygen -y -f ~/.ssh/id_ed25519 > ~/.ssh/id_ed25519.pub
chmod 644 ~/.ssh/id_ed25519.pub
Verify:
ssh-keygen -lf ~/.ssh/id_ed25519.pub
Change or Remove a Private Key Passphrase
Change passphrase:
ssh-keygen -p -f ~/.ssh/id_ed25519
Remove passphrase (enter old passphrase, then set new passphrase empty):
ssh-keygen -p -f ~/.ssh/id_ed25519
Known Hosts Management (Host Key, Not User Key)
Host keys are server identity records stored locally in ~/.ssh/known_hosts. They prevent man-in-the-middle attacks by detecting unexpected server identity changes.
Find an entry
ssh-keygen -F your_server_ip
Remove an entry (common after server rebuild)
ssh-keygen -R your_server_ip
Typical output:
# Host your_server_ip found: line 12
/home/user/.ssh/known_hosts updated.
SSH Server Host Keys (System-Level)
These are not your personal keys. They belong to the SSH server (sshd) and identify the server to clients.
Generate missing host keys (server-side, as root):
sudo ssh-keygen -A
Check host key fingerprints (server-side):
sudo ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub
sudo ssh-keygen -lf /etc/ssh/ssh_host_rsa_key.pub
Key Rotation Strategy
Two common approaches:
A) Rotate passphrase only (same key material)
- Useful when the key is still trusted but you want better protection
ssh-keygen -p -f ~/.ssh/wpserver_key
B) Rotate the key pair (new key material)
- Recommended after a suspected compromise, personnel changes, or compliance requirements
Steps:
- Generate a new key with a distinct name
- Install the new public key on the server
- Test login with the new key
- Remove the old public key from
authorized_keys
Example:
ssh-keygen -t ed25519 -f ~/.ssh/wpserver_key_2026 -C "wpserver-rotation"
Common Use Cases
| Use Case | Command | Why it matters |
|---|---|---|
| - | -- | |
| One key per VPS | ssh-keygen -t ed25519 -f ~/.ssh/vps_hetzner -C "hetzner" | Limits blast radius if one key leaks |
| Deployment key for Git | ssh-keygen -t ed25519 -f ~/.ssh/id_github_deploy -C "github-deploy" | Separates deploy access from admin access |
Restore missing .pub | ssh-keygen -y -f ~/.ssh/id_ed25519 > ~/.ssh/id_ed25519.pub | Avoids regenerating keys unnecessarily |
| Passphrase rotation | ssh-keygen -p -f ~/.ssh/vps_key | Improves security without replacing key |
| Fix host key mismatch | ssh-keygen -R server_ip | Cleans old host identity after rebuild |
| Audit known_hosts | ssh-keygen -lf ~/.ssh/known_hosts | Review stored server identities |
Best Practices
| Practice | Reason |
|---|---|
| -- | - |
Prefer ed25519 | Strong, fast, modern default |
| Use a unique key per purpose | Separates admin, deploy, and automation access |
Add meaningful comments (-C) | Easier key inventory and server auditing |
| Protect private keys with passphrases | Reduces impact if file is stolen |
Use ssh-agent instead of removing passphrases | Keeps keys encrypted on disk |
| Enforce strict file permissions | Prevents SSH from refusing keys |
| Back up private keys securely | Recovery if the local device fails (use encrypted storage) |
| Rotate keys on compromise or policy schedule | Limits long-term exposure |
Do not store private keys in plain text cloud drives, public repos, or shared folders. Use encrypted vaults or OS keychains where possible.
Quick Cheat Sheet
| Task | Command |
|---|---|
| - | - |
| Generate ED25519 key | ssh-keygen -t ed25519 -C "you@example.com" |
| Generate RSA 4096 key | ssh-keygen -t rsa -b 4096 -C "you@example.com" |
| Custom filename | ssh-keygen -t ed25519 -f ~/.ssh/myserver_key -C "myserver" |
| Change passphrase | ssh-keygen -p -f ~/.ssh/myserver_key |
| Extract public key | ssh-keygen -y -f ~/.ssh/myserver_key > ~/.ssh/myserver_key.pub |
| Show fingerprint | ssh-keygen -lf ~/.ssh/myserver_key.pub |
| Remove known_hosts entry | ssh-keygen -R your_server_ip |
| Find known_hosts entry | ssh-keygen -F your_server_ip |
| Generate server host keys | sudo ssh-keygen -A |