A security-focused guide to ssh-keygen — covering Ed25519 vs RSA algorithm selection, passphrase enforcement, authorized_keys file security, key rotation procedures, and fingerprint verification for production server access.
What is ssh-keygen?
The ssh-keygen command generates, manages, and converts SSH authentication keys. SSH public key authentication is the strongly recommended alternative to password-based SSH login: a private key (kept on the administrator’s workstation and protected by a passphrase) is paired with a public key (placed in ~/.ssh/authorized_keys on the server). The server verifies the client’s possession of the private key during the authentication handshake without the key itself ever being transmitted over the network. The algorithm choice (Ed25519, RSA-4096, ECDSA) significantly affects both security level and key size. Ed25519 is the current recommended algorithm: faster, shorter keys, and equivalent or better security than RSA-4096.
Syntax
ssh-keygen -t ed25519 -C 'comment'
ssh-keygen -t rsa -b 4096 -C 'comment'
ssh-keygen -lf /path/to/key.pub
ssh-keygen -p -f ~/.ssh/id_ed25519
ssh-keygen -R hostname-t specifies the algorithm type. -b specifies key size in bits (for RSA). -C adds a comment (usually email or hostname for identification). -lf shows the fingerprint of an existing public key. -p -f changes the passphrase of an existing key without regenerating it. -R removes a host entry from known_hosts.
Key Options and Flags
| Flag / Parameter | Description | Security Note |
|---|---|---|
-t ed25519 | Generate an Ed25519 key — recommended for new keys. 256-bit security, compact key size. | Ed25519 is faster, produces shorter keys, and is considered more secure than RSA-2048 |
-t rsa -b 4096 | Generate an RSA 4096-bit key — use when compatibility with older systems is required | RSA-2048 is the minimum acceptable size; 4096 is preferred for new keys when Ed25519 is not supported |
-t ecdsa -b 521 | Generate an ECDSA key using NIST P-521 curve | ECDSA has some implementation concerns with NIST curves — Ed25519 is preferred |
-C comment | Add a comment to the key (appears in authorized_keys for identification) | Use format 'username@hostname_YYYY-MM' to identify the key's origin and creation date |
-p -f keyfile | Change the passphrase on an existing key without regenerating | Use to add a passphrase to existing unprotected keys or rotate the passphrase |
-lf keyfile | Display the fingerprint and comment of a key file | Use SHA256 fingerprint format for comparison — it is more widely displayed in cloud provider consoles |
Common Use Cases
Generate and Deploy an Ed25519 Key Pair for a New Server
The complete workflow for setting up key-based authentication: generate the key pair on the workstation (never on the server), copy the public key to the server’s authorized_keys, verify the key authentication works, then disable password authentication in sshd_config.
# On your workstation:
ssh-keygen -t ed25519 -C "admin@company_$(date +%Y-%m)" -f ~/.ssh/id_ed25519_prodserver
# Copy public key to server
ssh-copy-id -i ~/.ssh/id_ed25519_prodserver.pub user@server
# Test key auth
ssh -i ~/.ssh/id_ed25519_prodserver user@server
# Only after confirming key auth works, disable passwords on serverRotate SSH Keys After a Security Incident
After any suspected private key exposure — laptop theft, accidental key push to a repository, shared access revocation — the compromised public key must be removed from all authorized_keys files and replaced with a new key pair. This is more operationally complex than initial deployment, especially at scale.
# Generate new key pair
ssh-keygen -t ed25519 -C "admin@company_rotated_$(date +%Y-%m)" -f ~/.ssh/id_ed25519_new
# Add new key to server BEFORE removing old key
ssh-copy-id -i ~/.ssh/id_ed25519_new.pub user@server
# Verify new key works
ssh -i ~/.ssh/id_ed25519_new user@server
# Remove old/compromised key from authorized_keys
ssh user@server 'grep -v "compromised_key_fingerprint" ~/.ssh/authorized_keys > /tmp/auth_new && mv /tmp/auth_new ~/.ssh/authorized_keys'Audit authorized_keys Files on a Server
Attackers who compromise a server often add their own public key to the root or admin user’s authorized_keys file for persistent SSH access. Regularly audit all authorized_keys files to verify they contain only expected keys. The comment field in each key line identifies the key’s claimed origin.
# Check all authorized_keys on the system
for user in $(awk -F: '$3>=1000{print $1}' /etc/passwd); do
HOME_DIR=$(getent passwd $user | cut -d: -f6)
AUTH_KEYS="$HOME_DIR/.ssh/authorized_keys"
[ -f "$AUTH_KEYS" ] && echo "=== $user ==" && cat "$AUTH_KEYS"
done
# Also check root
cat /root/.ssh/authorized_keys 2>/dev/nullSecurity Relevance: Algorithm Choice and Key Protection
The security of SSH key authentication depends on two factors: the cryptographic strength of the algorithm and the protection of the private key. Ed25519 (based on the Curve25519 elliptic curve) offers 128-bit security level with small key sizes and fast operations — it is not vulnerable to the implementation timing attacks that affect some RSA implementations, and its design avoids the NIST curve concerns associated with ECDSA. RSA-4096 provides approximately 140-bit security and is required when connecting to legacy systems that do not support Ed25519. RSA-2048 is the minimum acceptable size — shorter RSA keys (768, 1024) are cryptographically broken. The private key protection is equally critical: a private key without a passphrase is immediately usable by anyone who reads the key file. Key files should be permission 600, stored only on trusted workstations, and protected with a strong passphrase enforced by your SSH agent (ssh-agent or similar).
- Never generate SSH keys on the server — generate them on your workstation and copy only the public key to the server
- Private keys without passphrases are immediately usable by anyone who can read the file — always set a passphrase for production keys
- authorized_keys file permissions must be 600 (or 640) and the .ssh directory must be 700 — sshd refuses keys from world-readable files
- Never commit private key files to version control — scan repositories with tools like git-secrets or trufflehog to detect accidental key exposure
- RSA keys shorter than 2048 bits are cryptographically broken — generate new ones immediately if found on any system
Practical Examples
Generate an Ed25519 key with a descriptive comment and verify the fingerprint
ssh-keygen -t ed25519 -C "admin@prodserver_2026-03" -f ~/.ssh/id_ed25519_prod
# Display fingerprint for out-of-band verification
ssh-keygen -lf ~/.ssh/id_ed25519_prod.pub
# Set correct permissions
chmod 600 ~/.ssh/id_ed25519_prod
chmod 644 ~/.ssh/id_ed25519_prod.pubGenerates an Ed25519 key pair with a date-stamped comment for auditability. The fingerprint is displayed using SHA256 format by default in recent OpenSSH versions — this is the format used by GitHub, GitLab, and cloud provider consoles for key verification. Verify the fingerprint matches what you see in the cloud console or server log.
Secure the authorized_keys file with correct permissions
# On the server — fix permissions if incorrect
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chown -R $USER:$USER ~/.ssh
# Verify
ls -la ~/.ssh/
ls -la ~/.ssh/authorized_keyssshd rejects public keys from authorized_keys files with incorrect permissions. If SSH key authentication stops working unexpectedly, check these permissions first. The .ssh directory must be 700 (not readable by others), and authorized_keys must be 600 (owner read/write only).
List all public keys authorized for a user account with fingerprints
while IFS= read -r key; do
echo "$key" | ssh-keygen -l -f - 2>/dev/null
done < ~/.ssh/authorized_keysIterates over each key in authorized_keys and displays its fingerprint and comment. This allows you to verify that only expected keys are authorized and identify any unknown keys by their comment field. Unknown keys with no recognizable comment are a high-priority security finding.
Troubleshooting Common Issues
Problem: SSH key authentication fails even though the key is in authorized_keys
Solution: Check sshd verbose logs: journalctl -u sshd | grep 'Authentication refused'. Common causes: incorrect file permissions (authorized_keys must be 600, .ssh must be 700); the key type is not permitted in sshd_config; the username in the key comment contains characters that confuse sshd; or PubkeyAuthentication is set to no in sshd_config.
Problem: ssh-keygen fails with 'no such file or directory' for the output path
Solution: The destination directory does not exist or has incorrect permissions. Create it first: mkdir -p ~/.ssh && chmod 700 ~/.ssh. Then run ssh-keygen again. If specifying a custom path with -f, ensure the parent directory exists.
Problem: Old RSA keys are rejected by the server after an OpenSSH upgrade
Solution: Recent OpenSSH versions (8.8+) disable RSA with SHA-1 by default. If using RSA keys, ensure the server’s sshd_config permits the SHA-2 RSA variants: PubkeyAcceptedAlgorithms +ssh-rsa-sha2-256,ssh-rsa-sha2-512. Better: generate a new Ed25519 key, which is not affected by this change.
Summary
SSH key authentication is the most important security improvement over password-based SSH — it eliminates the brute force attack vector entirely. Use Ed25519 for all new key generation, always set a passphrase, generate keys on the workstation (never the server), and maintain an audit of authorized_keys across all managed servers. Rotate keys after any suspected exposure and audit authorized_keys files regularly for unauthorized entries.
- Generate Ed25519 keys with
ssh-keygen -t ed25519— it provides stronger security with smaller keys than RSA - Always set a passphrase — a passphrase-protected key requires both the key file and the passphrase to use
- Audit
~/.ssh/authorized_keyson all servers regularly — an unauthorized key is a confirmed persistent access backdoor
Related Commands
sshd_config server-side hardening • ssh client-side hardening • chown for authorized_keys ownership management • chmod for .ssh directory permissions
Are All Your Server SSH Keys Audited and Up to Date?
INTRAM implements Ed25519 key authentication, audits authorized_keys files, enforces passphrase policies, and manages key rotation across all managed Linux servers.
Secure My SSH Key Management