Back to Blog
Guidessshsecurityauthentication

SSH Keys Explained: Secure Authentication Without Passwords

Understand SSH key authentication from key generation to agent forwarding. Learn RSA vs Ed25519, SSH config management, and security best practices.

Loopaloo TeamFebruary 5, 202614 min read

SSH Keys Explained: Secure Authentication Without Passwords

If you've ever connected to a remote server, pushed code to GitHub, or tunneled into a database behind a firewall, you've almost certainly used SSH. The Secure Shell protocol is one of the foundational technologies of modern computing infrastructure, and at its heart lies a beautifully simple idea: you can prove your identity without ever transmitting a secret. Understanding how SSH key-based authentication works—and why it's vastly superior to passwords—is essential knowledge for any developer, system administrator, or security-conscious technologist.

A Brief History of SSH

Before SSH, remote access to Unix systems relied on protocols that now seem recklessly insecure. Telnet, developed in 1969, transmitted everything—including passwords—in plain text across the network. Anyone with a packet sniffer on the same network segment could read your credentials in real time. The Berkeley r-commands (rlogin, rsh, rcp), introduced in the early 1980s, offered modest convenience improvements but no meaningful encryption. In an era when networks were small, trusted, and physically controlled, this felt acceptable. As the internet grew, it became a catastrophic liability.

SSH was created in 1995 by Tatu Ylönen, a Finnish researcher at the Helsinki University of Technology, in direct response to a password-sniffing attack on his university's network. The protocol encrypted the entire session, including the authentication exchange, making eavesdropping useless. Ylönen's original implementation was freely available and spread rapidly through the Unix community. In 1999, the OpenBSD project began developing OpenSSH, a completely open-source implementation that has since become the de facto standard on virtually every Linux distribution, macOS, and (since 2018) Windows 10. Today, SSH is so deeply embedded in computing infrastructure that billions of automated connections traverse it every day.

How Public-Key Cryptography Works

To understand SSH key authentication, you need a basic grasp of asymmetric (public-key) cryptography. In symmetric cryptography, the same key encrypts and decrypts data—like a physical lock where both parties share identical copies of the same key. The problem is obvious: you need a secure way to share that key in the first place, which is precisely the problem you're trying to solve.

Asymmetric cryptography resolves this circular dependency by using a mathematically related pair of keys: a public key and a private key. Data encrypted with the public key can only be decrypted with the corresponding private key, and vice versa. Critically, knowing the public key does not allow you to derive the private key—at least not within any computationally feasible timeframe. This means you can freely distribute your public key to the entire world. Anyone can use it to encrypt a message that only you can read, and you can use your private key to create digital signatures that anyone can verify using your public key.

The mathematical relationship between the keys depends on the algorithm. RSA relies on the difficulty of factoring the product of two very large prime numbers. Elliptic curve algorithms like Ed25519 and ECDSA rely on the difficulty of the elliptic curve discrete logarithm problem. In both cases, operations in one direction (multiplying primes, or computing a point on a curve) are computationally trivial, while reversing the operation (factoring, or computing the discrete logarithm) is computationally infeasible with current technology.

RSA vs. Ed25519 vs. ECDSA

When generating an SSH key pair, you must choose an algorithm, and the choice matters more than many developers realize. RSA, the oldest and most widely supported algorithm, generates key pairs by selecting two large random primes, multiplying them to produce a modulus, and computing public and private exponents. RSA keys are typically 2048 or 4096 bits long. While RSA at 4096 bits remains secure, the keys are large and the cryptographic operations are relatively slow compared to modern alternatives.

ECDSA (Elliptic Curve Digital Signature Algorithm) uses elliptic curves defined by NIST (the National Institute of Standards and Technology) to achieve equivalent security with much shorter keys. A 256-bit ECDSA key provides roughly the same security as a 3072-bit RSA key. However, ECDSA has a subtle and dangerous property: it requires a high-quality source of randomness during every signing operation. If the random number generator is even slightly biased, the private key can be recovered from a collection of signatures. This vulnerability has been exploited in practice, most notably in the 2010 PlayStation 3 private key extraction.

Ed25519, introduced by Daniel J. Bernstein and colleagues, uses a twisted Edwards curve called Curve25519 and is designed to avoid the pitfalls of ECDSA. It uses deterministic nonces derived from the private key and the message being signed, eliminating the dependency on a random number generator during signing. Ed25519 keys are compact (256 bits), authentication operations are extremely fast, and the algorithm has a clean, well-analyzed security proof. For these reasons, Ed25519 is now the recommended choice for new SSH key pairs, and you can generate one instantly with an SSH Key Generator. Unless you need to connect to a legacy system that only supports RSA, Ed25519 should be your default.

The Key Generation Process

When you generate an SSH key pair—whether using ssh-keygen on the command line or a web-based tool—the software performs several steps. First, it generates the cryptographic key material: for Ed25519, this means producing 32 bytes of random data as the private key seed, then computing the corresponding public key through elliptic curve point multiplication. For RSA, the process involves generating two large random primes, computing their product, and deriving the public and private exponents using modular arithmetic.

The private key is then encoded (typically in PEM or OpenSSH format) and optionally encrypted with a passphrase using a symmetric cipher like AES-256. The passphrase doesn't change the key itself—it encrypts the file that stores the key. If someone steals your private key file but doesn't know the passphrase, they can't use the key. The public key is encoded in a single-line format that includes the algorithm identifier, the base64-encoded key data, and an optional comment (usually your email address).

The resulting key pair consists of two files: the private key (typically ~/.ssh/id_ed25519) and the public key (typically ~/.ssh/id_ed25519.pub). The private key must be kept secret and protected with appropriate file permissions. The public key can be freely shared, posted on your website, uploaded to GitHub, or distributed to any server you want to access.

The Authentication Flow

Understanding the actual authentication handshake demystifies what happens when you ssh into a server. When the SSH client connects, the server and client first negotiate protocol versions and encryption algorithms for the session. They then perform a Diffie-Hellman key exchange to establish a shared session key that encrypts all subsequent communication—this happens before any authentication, so your credentials are protected even if someone is watching the connection.

Once the encrypted channel is established, the client offers its public key to the server. The server checks whether that public key appears in the ~/.ssh/authorized_keys file for the target user account. If it finds a match, the server generates a random challenge, encrypts it with the client's public key, and sends it to the client. The client decrypts the challenge using its private key and sends back a hash of the decrypted value combined with the session identifier. The server verifies this response, and if it matches, authentication succeeds. At no point does the private key leave the client machine, and at no point is the private key transmitted over the network. This is fundamentally different from password authentication, where the password itself must be sent to the server.

SSH Agent and Agent Forwarding

Typing your key's passphrase every time you initiate an SSH connection would be tedious, and this is where the SSH agent comes in. The SSH agent (ssh-agent) is a background process that holds your decrypted private keys in memory. When you add a key to the agent using ssh-add, you enter the passphrase once, and the agent handles all subsequent authentication requests for the duration of your session. On macOS, the system keychain integrates with the SSH agent, allowing you to store passphrases persistently so they survive reboots.

Agent forwarding extends this convenience across multiple hops. If you SSH from your laptop to Server A and then from Server A to Server B, agent forwarding allows Server A to relay authentication requests back to the agent running on your laptop. This means you can authenticate to Server B using the private key that exists only on your laptop, without copying your private key to Server A. However, agent forwarding carries a security risk: anyone with root access on Server A can use your forwarded agent to authenticate as you to any server your key can access. For this reason, agent forwarding should only be enabled for trusted hosts, and the newer ProxyJump feature (-J flag) is often a safer alternative for multi-hop connections.

Passphrase Protection

A passphrase on your private key is your second line of defense. If your private key file is stolen—through a compromised backup, a stolen laptop, or a misconfigured file share—the passphrase prevents immediate use. Without the passphrase, the attacker has a file full of encrypted data that's computationally infeasible to brute-force if the passphrase is strong. Using a Password Generator to create a long, random passphrase for your SSH key adds significant protection against this scenario.

Modern OpenSSH uses the bcrypt key derivation function to convert your passphrase into the encryption key that protects the private key file. Bcrypt is deliberately slow, which means brute-force attacks against the passphrase must spend significant computation time per guess. This is a dramatic improvement over older versions that used standard MD5 hashing, which could be brute-forced at billions of guesses per second on commodity hardware.

The SSH Config File

As you accumulate more servers, Git hosts, and cloud instances, typing full SSH commands with hostnames, usernames, ports, and key file paths becomes unwieldy. The SSH config file (~/.ssh/config) solves this by letting you define named hosts with preconfigured settings. Instead of typing ssh -i ~/.ssh/special_key -p 2222 deployer@staging.example.com, you define a host block and then simply type ssh staging.

The config file supports a rich set of directives. You can specify different identity files for different hosts, set up jump hosts for bastion server access, configure connection timeouts, enable or disable agent forwarding on a per-host basis, and even set up local port forwarding rules that activate automatically when you connect. For teams, a shared SSH config template ensures that everyone uses consistent settings, reducing the "works on my machine" problem for remote access.

Common Use Cases

SSH key authentication underpins some of the most critical workflows in modern development. Git hosting platforms like GitHub, GitLab, and Bitbucket all support SSH key authentication for repository operations. By registering your public key with the platform, you can push and pull without entering credentials, and without storing passwords or tokens on disk. For organizations, SSH keys tied to individual developer accounts provide an auditable trail of who accessed which repositories.

Server administration is the original use case, and it remains essential. SSH provides not just shell access but also secure file transfer through SFTP and SCP. Port forwarding through SSH tunnels allows you to securely access services on remote networks—forwarding a database port through an SSH connection to a bastion host is a common pattern for accessing production databases during incident response. Reverse tunnels allow services behind firewalls to expose ports to the outside world through an established SSH connection, which is useful for IoT devices, development machines behind corporate NATs, and other scenarios where inbound connections aren't possible.

Key Management Best Practices

Good SSH key hygiene is simpler than most security practices, but it's still frequently neglected. File permissions are the most common source of problems: your private key file must be readable only by you (mode 600), and the ~/.ssh directory must be accessible only by you (mode 700). If the permissions are too permissive, OpenSSH will refuse to use the key, which is a safety feature, not a bug.

Key rotation is important but often overlooked. Just as you should periodically change passwords, you should periodically generate new SSH key pairs, distribute the new public key to your servers, and decommission the old one. This limits the window of exposure if a key is compromised without your knowledge. When a team member leaves an organization, their public key should be promptly removed from all authorized_keys files—and from Git hosting platform organization settings.

The known_hosts file deserves attention too. The first time you connect to a server, SSH records the server's host key fingerprint. On subsequent connections, SSH verifies that the server presents the same key, protecting you against man-in-the-middle attacks. If the fingerprint changes—because the server was reinstalled, for instance—SSH warns you loudly. You should not blindly accept changed host keys without verifying the change through an out-of-band channel.

SSH Certificates: An Alternative Approach

For organizations managing hundreds or thousands of servers, individual authorized_keys entries become unmanageable. SSH certificates offer a scalable alternative. Instead of distributing public keys to every server, you set up a certificate authority (CA) that signs user public keys. Servers are configured to trust the CA, and any key signed by the CA is automatically accepted. Certificates can include expiration times, restricting access to a defined window, and they can embed restrictions on which hosts or commands the certificate holder is authorized to use.

The certificate model inverts the trust relationship: instead of each server maintaining its own list of authorized keys, a central authority issues time-limited credentials. This makes onboarding and offboarding dramatically simpler—issuing a certificate grants access, and the certificate's natural expiration revokes it without touching any server configuration. Facebook, Google, and Netflix have all publicly described their adoption of SSH certificates at scale.

Troubleshooting Common Problems

The most frequent SSH key problem is incorrect file permissions. If your private key file is group-readable or world-readable, OpenSSH will print a warning about "unprotected private key file" and refuse to use it. The fix is straightforward: chmod 600 ~/.ssh/id_ed25519 and chmod 700 ~/.ssh. On shared hosting or certain NFS mounts, filesystem limitations may prevent setting proper permissions, requiring workarounds like using a key stored in a different location.

Key format mismatches are another common issue. Older tools may generate keys in PEM format while newer versions of OpenSSH default to their own format. If you encounter errors about invalid key formats, the ssh-keygen -p -m PEM -f keyfile command can convert between formats. Similarly, keys generated on Windows with tools like PuTTYgen use the PPK format, which must be converted to OpenSSH format before use on Unix systems.

Authentication failures where "everything looks right" often come down to the authorized_keys file format. Each key must be on a single line with no line breaks. Extra whitespace, invisible characters from copy-paste operations, or a missing newline at the end of the file can all cause silent failures. Running ssh -vvv user@host activates verbose logging and reveals exactly where in the authentication process things go wrong, making it the single most useful debugging technique for SSH connection problems.

The combination of mathematical elegance, practical security, and universal adoption makes SSH key authentication one of the great success stories of applied cryptography. Whether you're generating your first key pair or managing a fleet of certificates across an enterprise, understanding the principles behind the protocol helps you make better decisions about the tradeoffs between security, convenience, and operational complexity.

Related Tools

Related Articles

Try Our Free Tools

200+ browser-based tools for developers and creators. No uploads, complete privacy.

Explore All Tools