How to create SSH keys and manage multiple keys

How to create SSH keys, copy them safely to a server, and configure a different key for each server or Git hosting account.

Check for existing SSH keys

SSH keeps user configuration and keys in the hidden ~/.ssh directory. List its contents before creating anything so you do not accidentally overwrite an existing key:

ls -la ~/.ssh

It is normal for the directory not to exist yet. Create it with permissions that allow only your user to access it:

mkdir -p ~/.ssh
chmod 700 ~/.ssh

For a generated key pair, the file ending in .pub is the public key and the matching file without that suffix is the private key.

Generate an SSH key

Create an Ed25519 key on your local machine. Ed25519 is the default in current OpenSSH releases and is a good choice for most users:

ssh-keygen -t ed25519 -C "bob@laptop for example.net" -f ~/.ssh/id_ed25519_example

The comment supplied with -C is only a label. A descriptive label makes the key easier to recognize later. The -f option gives this key a unique name, which is useful when you manage more than one identity.

If the server does not support Ed25519, create an RSA key instead. A 3072-bit RSA key is sufficient for most uses:

ssh-keygen -t rsa -b 3072 -C "bob@laptop for example.net" -f ~/.ssh/id_rsa_example

ssh-keygen asks for a passphrase. Use a strong, unique passphrase so a stolen private-key file cannot immediately be used. An SSH agent can remember the unlocked key during your session, so you do not need to type the passphrase for every connection.

The Ed25519 command creates two files:

~/.ssh/id_ed25519_example

The private key. Keep it secret and only on devices from which you connect.

~/.ssh/id_ed25519_example.pub

The public key. Install this on servers and services you want to access.

You may inspect or copy the public key:

cat ~/.ssh/id_ed25519_example.pub

It is one line and looks approximately like this:

ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG9exampleonlynotarealkey bob@laptop for example.net

To identify a key without displaying all of it, print its fingerprint:

ssh-keygen -lf ~/.ssh/id_ed25519_example.pub

Copy the public key to a server

Cloud providers often let you add a public key while creating a server. If you do that, the provider installs it for the user you selected. Do not assume it belongs in /root: the usual location is ~/.ssh/authorized_keys in the account you will log in to.

If the server already accepts your password or another key, install the new public key with one of the following methods.

Method 1: ssh-copy-id

If ssh-copy-id is installed, it is the simplest option:

ssh-copy-id -i ~/.ssh/id_ed25519_example.pub [email protected]

For a server listening on port 5555, add -p:

ssh-copy-id -i ~/.ssh/id_ed25519_example.pub -p 5555 [email protected]

Some systems, including macOS, may not include ssh-copy-id by default. The next method only needs the standard SSH client.

Method 2: send it over SSH

This command appends the public key and applies permissions accepted by the usual sshd configuration:

cat ~/.ssh/id_ed25519_example.pub | ssh -p 5555 [email protected] \
  'umask 077; mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys'

Omit -p 5555 if the server uses the default SSH port, 22. Running the command more than once may add duplicate lines, which is harmless but untidy.

Method 3: copy it manually

Display the public key:

cat ~/.ssh/id_ed25519_example.pub

Log in to the server and paste that entire single line into ~/.ssh/authorized_keys. Then fix the remote permissions:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

Only copy the file ending in .pub. The private key never belongs in authorized_keys or anywhere else on the remote server.

Verify the server and test the connection

On the first connection, SSH shows the server's host-key fingerprint. Verify it against a fingerprint supplied by the server administrator or cloud-provider console before accepting it. This check protects you from connecting to an impostor.

Keep your current server session open while testing the new key in a second terminal. That way you can repair authorized_keys if the new login fails:

ssh -i ~/.ssh/id_ed25519_example -o IdentitiesOnly=yes -p 5555 \
  [email protected]

The -i option selects the private identity file. If authentication fails, add -v for diagnostic output, or -vvv for more detail:

ssh -vvv -i ~/.ssh/id_ed25519_example -o IdentitiesOnly=yes \
  [email protected]

Use an SSH agent

An SSH agent keeps decrypted private keys in memory. Many desktop environments start one automatically. If yours does not, start an agent and add the key:

eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519_example

List the keys currently available through the agent with:

ssh-add -l

The agent saves you from repeatedly entering a passphrase, but it does not replace one. A private key protected by a passphrase is safer at rest.

Manage multiple SSH keys

You do not need a separate key for every server. A key per client device is a common starting point because you can revoke a lost device without disrupting the others. Separate keys can also be useful for personal and work accounts or other trust boundaries.

OpenSSH recognizes default private-key names such as id_ed25519 and id_rsa. For custom names, or when an agent holds several keys, use ~/.ssh/config to select the right identity for each destination.

Create the config file as your own user, without sudo, and restrict its permissions:

touch ~/.ssh/config
chmod 600 ~/.ssh/config

Add one Host block per destination:

Host myserver
  HostName 123.45.56.78
  User bob
  Port 5555
  IdentityFile ~/.ssh/id_ed25519_example
  IdentitiesOnly yes
 
Host mysecondserver
  HostName example.org
  User alice
  IdentityFile ~/.ssh/id_ed25519_example_org
  IdentitiesOnly yes

The options mean:

Host
A local alias used on the command line.
HostName
The server's domain name or IP address.
User
The account name on the remote server.
Port
The SSH port. Leave it out when the server uses port 22.
IdentityFile
The local private key to use, without the .pub suffix.
IdentitiesOnly

Offer only the configured identity instead of trying every key in the agent. This also avoids “Too many authentication failures” errors.

You can now connect using the alias:

ssh myserver

To see the final configuration SSH will use, run:

ssh -G myserver

Multiple accounts on the same Git host

Aliases are also useful when you have personal and work accounts on the same Git provider:

Host github-personal
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519_github_personal
  IdentitiesOnly yes
 
Host github-work
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519_github_work
  IdentitiesOnly yes

Use the matching alias in each repository's remote URL:

git remote set-url origin git@github-work:company/project.git

The alias changes only how your local SSH client chooses a key. Both entries still connect to github.com.

Rotate or revoke a key

If a private key may be compromised, remove its public-key line from every server's ~/.ssh/authorized_keys file and every service account where you registered it. Remove it from the agent with ssh-add -d ~/.ssh/id_ed25519_example, then generate a new key.

For routine rotation, install and test the replacement key before removing the old one so you do not lock yourself out. Keep a known-working session open until the replacement login succeeds.

The OpenSSH ssh-keygen, ssh_config, and sshd manual pages contain the complete option and file-format references.