Right, let’s talk about the one thing standing between you and a password-free, secure connection to your servers: your SSH key pair. This isn’t just a password replacement; it’s a fundamental shift from “something you know” to “something you have.” We’re generating cryptographic proof of your identity. And we’re going to do it the right way, not the way some dusty old tutorial from 2005 tells you to.

The workhorse for this job is ssh-keygen. It doesn’t have a flashy GUI because it doesn’t need one. It’s a precision instrument, and by the time we’re done, you’ll know how to wield it.

The Two Key Types You Actually Need to Care About

Forget DSA. Forget ECDSA unless you have a very specific reason. For 99.9% of us, the debate boils down to two choices: the old guard and the new hotness.

RSA is the venerable old warhorse. It’s everywhere. It’s compatible with everything, from that ancient mainframe your company refuses to retire to the latest cloud hypervisor. The critical thing to understand with RSA is its key size. The old default was 2048 bits. As of 2022, most ssh-keygen implementations will bump that to 3072 bits, and that’s what you should use if you go the RSA route. Why? Because while 2048 is still technically secure, the wall of safety is getting closer. 3072 gives you a much more comfortable margin. 4096 is overkill for SSH—it’s slower and the key files are larger, all for a security margin you simply don’t need. Don’t be that person.

Ed25519 is the brilliant newcomer. It’s based on elliptic curve cryptography, which is a fancy way of saying it provides security equivalent to a massive RSA key (like 3000+ bits) with a tiny, elegant, and incredibly fast key. An Ed25519 key is only 256 bits. It’s more secure against certain types of attacks than RSA, it generates in a blink, and it makes connections slightly faster. The catch? While support is almost universal now, you might still run into a crusty old system (looking at you, Cisco world) that gags on it. If you know your target supports it, use it. It’s objectively better.

Here’s how you generate both. Open your terminal and run one of these.

# Generate a rock-solid 3072-bit RSA key
ssh-keygen -t rsa -b 3072

# Generate a modern Ed25519 key (note: no -b flag, the size is fixed)
ssh-keygen -t ed25519

What ssh-keygen Actually Does (And Those Prompts)

When you run that command, it does two things:

  1. It generates a private key (your secret, never share it) and a public key (the part you scatter everywhere).
  2. It asks you where to save the files and for a passphrase.

The “Enter file” prompt is your chance to give it a sensible name. The default is id_rsa or id_ed25519 in your ~/.ssh directory. Naming it something like id_rsa_work_aws is a fantastic practice. It keeps things organized if you have multiple keys (you will).

Next, it asks for a passphrase. This is the single most argued-about point in SSH. Always set a passphrase. Let’s be direct: not setting one is lazy and insecure. Your private key is a file. If it’s stolen (backup gone wrong, laptop stolen, ~/.ssh directory accidentally committed to a public GitHub repo—it happens!), a key without a passphrase is instantly usable. A passphrase encrypts the key file on disk. Yes, it means you have to type it to unlock it, but we’ll fix that annoyance in the next section with ssh-agent. The passphrase is your last line of defense. Make it strong, but make it something you can live with.

Where the Keys Live and What to Do With Them

After generation, you’ll find two files in ~/.ssh:

  • id_ed25519 (or whatever you named it): This is your PRIVATE KEY. Its permissions must be locked down. ssh-keygen does this for you (600), but if you ever move it, enforce this: chmod 600 ~/.ssh/id_ed25519. If the permissions are too open, the SSH client will refuse to use it, which is a fantastic, paranoid safety feature.
  • id_ed25519.pub: This is your PUBLIC KEY. This is the one you can shout from the rooftops. Its contents look like a jumble of text starting with ssh-ed25519 (or ssh-rsa).

This public key is what you need to append to the ~/.ssh/authorized_keys file on any server you want to access. You can’t just scp the .pub file over; you have to append its contents to that specific file on the remote host.

# The classic way to get your key onto a server (it will prompt for your password *this one last time*)
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@your.server.com

# The manual, "I-trust-myself-more" way, if ssh-copy-id isn't available
cat ~/.ssh/id_ed25519.pub | ssh user@your.server.com "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

Best Practices and Pitfalls

  • Use a passphrase. We covered this. Do it.
  • Use a descriptive key name. -f ~/.ssh/id_ed25519_personal is clearer than the default.
  • Don’t reuse keys. Use a different key for your personal GitHub, your work AWS, and your homelab. If one gets compromised, you only have to replace that one, not everything everywhere. This is where named keys and the SSH config file (~/.ssh/config) become your best friends.
  • The -a flag for Ed25519: This is a niche but important one. The -a flag sets the number of Key Derivation Function (KDF) rounds, making brute-forcing a stolen encrypted key much slower. The default is 16. You can crank it to 100 or so to make it tougher, but it will also make unlocking the key with ssh-agent slightly slower. It’s a trade-off for high-security environments.
    ssh-keygen -t ed25519 -a 100
    
  • Verify permissions. If your connection is mysteriously rejected, 90% of the time it’s because the permissions on ~/.ssh (should be 700) or ~/.ssh/authorized_keys (should be 600) on the remote server are too permissive. The SSH daemon is, rightly, incredibly paranoid.