A Practical Guide to SSH Key Generation and Secure Access
SSH key generation is a foundational skill for modern system administration and secure remote access. Rather than relying on passwords, SSH keys provide a stronger, more convenient method of authentication. This guide explains what SSH keys are, why they matter, and how to generate, manage, and rotate them effectively. By following best practices for SSH key generation, you can reduce attack surfaces, simplify access control, and improve the overall security of your infrastructure.
What are SSH keys and why generate them?
SSH keys come in pairs: a private key kept on your device and a public key placed on the servers you want to access. During login, the server challenges the client to prove possession of the private key. This process happens without transmitting the private key over the network. The result is a stronger form of authentication than passwords, especially when combined with a passphrase protecting the private key.
The core idea behind SSH key generation is to create this pair in a way that is cryptographically sound and easy to manage. A well-planned SSH key strategy reduces the risk of credential theft and supports better auditing and rotation across teams and machines.
Key types: what to choose
When you perform SSH key generation, you typically select a type for the key pair. The most common options are RSA, ECDSA, and Ed25519. Each has trade-offs in compatibility, performance, and security. In practice, Ed25519 is the recommended default for new deployments because it offers strong security with smaller key sizes, performs well, and is resistant to several classes of side-channel attacks. RSA remains widely supported, but with modern guidance suggesting a minimum of 2048 bits and ideally 3072 or 4096 bits for sensitive access. ECDSA is less favored today due to interoperability quirks and varying security interpretations.
For most teams, Ed25519 with a strong passphrase and careful key management provides the best balance between security and usability. If you must support older systems or clients that do not support Ed25519, RSA 4096-bit keys with a robust passphrase and routine rotation are a viable alternative. Importantly, avoid reusing the same key across multiple servers or roles whenever possible.
Choosing a convention and naming keys
Establish a consistent naming convention for SSH keys to simplify inventory and rotation. A practical approach is to name keys by machine and purpose, such as id_ed25519_workstation or id_rsa_prod_server. Include a comment with your email or project in the key’s label during generation, using the -C option. This makes it easier to identify the key later when reviewing access controls, auditing logs, or revoking access.
Generating SSH keys: step-by-step
The exact commands vary slightly by operating system, but the core process is the same: invoke the key generation tool, choose a type, set a passphrase, and save the private key to a safe location. Here are representative workflows for common environments.
On Linux and macOS (OpenSSH)
# Generate an Ed25519 key pair with a descriptive comment
ssh-keygen -t ed25519 -C "user@example.com" -a 100 -f ~/.ssh/id_ed25519
# Explanation:
# -t ed25519: key type
# -C comment: descriptive label
# -a 100: rounds of KDF (more rounds increases resistance to brute-force)
# -f: output file for private key (public key will be id_ed25519.pub)
# You will be prompted for a passphrase to protect the private key.
# If you prefer no passphrase (not recommended), pass an empty string.
Notes:
– Ed25519 is the default and recommended type for new keys.
– The -a option enhances security by increasing the work factor of the passphrase protection.
– Always use a strong, unique passphrase for the private key.
# If you need RSA (for compatibility reasons), you can use:
ssh-keygen -t rsa -b 4096 -C "user@example.com" -a 100 -f ~/.ssh/id_rsa
On Windows with OpenSSH (PowerShell)
# OpenSSH is included by default on Windows 10/11. Run the same commands as Linux/macOS:
ssh-keygen -t ed25519 -C "user@example.com" -a 100 -f %USERPROFILE%\.ssh\id_ed25519
# Or RSA if needed:
# ssh-keygen -t rsa -b 4096 -C "user@example.com" -a 100 -f %USERPROFILE%\.ssh\id_rsa
Important considerations during generation
- Passphrase protection adds a second factor for your private key. If the private key is ever compromised, the attacker would still need the passphrase to use it.
- Store private keys with restrictive permissions. On Unix-like systems, the private key file should be 600 and the .ssh directory should be 700.
- Keep public keys readable by all; the public key is intended to be shared or added to servers via authorized_keys.
Distributing and deploying SSH public keys
After generating SSH keys, you need to deploy the public key to the servers you want to access. This is typically done by placing the public key into the remote user’s ~/.ssh/authorized_keys file. There are several practical methods to achieve this safely:
- ssh-copy-id: A convenience utility that appends the public key to the remote authorized_keys, handling permissions correctly. Example: ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server.example.com
- Manual copy: If ssh-copy-id isn’t available, you can manually append the contents of id_ed25519.pub to ~/.ssh/authorized_keys on the server. Ensure the server’s permissions are secure (400 or 600 for the file, 700 for the directory).
- Automation: For larger fleets, consider infrastructure as code or configuration management tools to manage authorized_keys across machines with per-user and per-server granularity.
Using an SSH agent and managing passphrases
An SSH agent can hold unlocked private keys in memory, so you don’t have to re-enter the passphrase for every connection. This improves workflow while preserving security. Start the agent and add your key as follows:
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
If you generate multiple keys for different roles or machines, you can manage them within an agent or run separate agents as needed. Remember that the agent stores keys in memory; if a machine is compromised, the attacker might access those keys unless you lock the session.
Best practices for ongoing SSH key management
- Rotate keys regularly. Establish a cadence for reviewing and updating SSH keys, especially for highly privileged accounts.
- Limit where a single key can be used. Prefer separate keys for different servers or teams to minimize blast radius if a key is compromised.
- Disable password authentication on servers where feasible. This compels the use of SSH keys and reduces social engineering risks tied to weak passwords.
- Audit and monitor. Keep an inventory of all SSH keys and their associated machines. Revoke or revoke access when a user leaves the team or a machine is decommissioned.
- Secure backup strategy. Back up your private keys securely (encrypted backups) and protect access to backup locations with strict permissions.
Common pitfalls to avoid
Several mistakes can undermine the security of SSH key-based authentication. Be mindful of these:
- Using the same private key across many devices or servers.
- Forgetting to protect private keys with a passphrase on shared machines or laptops.
- Setting overly permissive file permissions that expose private keys to other users.
- Relying on outdated algorithms or weak key sizes (for example, RSA with small keys or outdated curves).
- Neglecting to update authorized_keys when a user should no longer have access.
Cross-platform considerations
Whether you work primarily on Linux, macOS, or Windows, the fundamentals of SSH key generation stay the same. The main differences lie in the available tools and default file paths. Linux and macOS ship with OpenSSH client by default, making commands like ssh-keygen and ssh-copy-id readily available. Windows now includes OpenSSH in recent builds, enabling the same workflows in PowerShell. If you rely on legacy Windows tooling, PuTTY and PuTTYgen provide alternative means to generate and manage keys, followed by converting formats if needed for OpenSSH compatibility.
Putting it all together: a practical workflow
For a typical developer or sysadmin, a practical SSH key generation workflow looks like this: generate an Ed25519 key with a strong passphrase, save it to a dedicated location, distribute the public key to servers using ssh-copy-id or manual copy, add the private key to an SSH agent for convenience, and enforce server-side configurations that favor key-based authentication. With consistent naming, careful rotation, and diligent auditing, you create a robust foundation for secure remote access that scales across your organization.
Conclusion
SSH key generation is more than a technical task; it is a security discipline. By choosing modern key types, protecting private keys with passphrases, and following disciplined distribution and rotation practices, you reduce risk and improve control. The routine of generating SSH keys, using ssh-keygen, managing authorized_keys, and leveraging an SSH agent forms a repeatable, auditable workflow that aligns with contemporary security standards. Embrace these practices to ensure that SSH keys remain a strength rather than a vulnerability in your infrastructure.