How to generate an SSH key on macOS

macOS ships OpenSSH, so a key is one command away. Create an Ed25519 key, keep its passphrase in the Keychain and put the public key on GitHub or a server.

updated

Quick answer. Open Terminal and run the command below, press Return to keep the default file and type a passphrase. Your public key is ~/.ssh/id_ed25519.pub; pbcopy puts it on the clipboard.

ssh-keygen -t ed25519 -C "[email protected]"
pbcopy < ~/.ssh/id_ed25519.pub

What an SSH key is and why you want one

An SSH key is a pair of files. The private key stays on your Mac and proves who you are. The public key is safe to hand out: you paste it into GitHub, GitLab or a server's authorized_keys file, and from then on that service lets in whoever holds the matching private key.

Compared with a password, a key cannot be guessed, is never sent to the server, and cannot be phished on a fake login page. GitHub no longer accepts account passwords for git over HTTPS, so for many people a key is simply the easiest way to push code. On a server, keys let you turn off password logins altogether, which ends the endless brute-force attempts every public machine sees.

A passphrase encrypts the private key on disk. macOS can store that passphrase in your login Keychain, so you get the protection without typing it on every connection.

How to generate an SSH key on Mac

  1. Open Terminal

    Press Cmd + Space, type Terminal and press Return. Every version of macOS ships OpenSSH, so there is nothing to install. Check the version if you like:

    ssh -V
  2. Check for existing keys

    List the contents of your .ssh folder. If you already see id_ed25519 and id_ed25519.pub, you have a key and can skip to step 4, or give the new one a different file name so you do not overwrite it. "No such file or directory" just means you have no keys yet.

    ls -al ~/.ssh
  3. Generate the key pair

    Run ssh-keygen with the Ed25519 type and a comment that identifies the key, usually your email. Press Return to accept the default file location, then type a passphrase twice.

    ssh-keygen -t ed25519 -C "[email protected]"

    This writes the private key to ~/.ssh/id_ed25519 and the public key to ~/.ssh/id_ed25519.pub, and creates ~/.ssh if it is missing. If a server you use is too old for Ed25519, use ssh-keygen -t rsa -b 4096 instead.

  4. Add the key to ssh-agent and the Keychain

    macOS starts ssh-agent for you through launchd. Add the key and store its passphrase in the login Keychain so you are not asked again:

    ssh-add --apple-use-keychain ~/.ssh/id_ed25519

    On macOS 11 Big Sur and older the flag is -K instead of --apple-use-keychain.

  5. Configure ~/.ssh/config

    So the key is loaded automatically after a reboot, add these lines to ~/.ssh/config (create the file if it does not exist):

    Host *
      AddKeysToAgent yes
      UseKeychain yes
      IdentityFile ~/.ssh/id_ed25519

    UseKeychain is an Apple addition. If you share this file with Linux machines, put IgnoreUnknown UseKeychain above it so their OpenSSH does not reject the file.

  6. Copy the public key where you need it

    Copy the public key to the clipboard and paste it into GitHub, GitLab or your hosting panel, or install it on a server with ssh-copy-id, which macOS includes:

    pbcopy < ~/.ssh/id_ed25519.pub
    ssh-copy-id -i ~/.ssh/id_ed25519.pub user@host

What ssh-keygen asks you

A complete run looks like this (your fingerprint and picture will differ):

$ ssh-keygen -t ed25519 -C "[email protected]"
Generating public/private ed25519 key pair.
Enter file in which to save the key (/Users/you/.ssh/id_ed25519):
Enter passphrase for "/Users/you/.ssh/id_ed25519" (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/you/.ssh/id_ed25519
Your public key has been saved in /Users/you/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:I2McFhOvOOgBGIf3aLmk0z7TTKxZoLZ32hK6Bxbk7Tw [email protected]
The key's randomart image is:
+--[ED25519 256]--+
|...   +.         |
|o+.    +         |
|=..+  o .        |
| +*o.+ o         |
| **+o * S        |
|+=oE+o o .       |
|oo=Bo            |
| o*++.           |
| .+++.           |
+----[SHA256]-----+

Older OpenSSH releases word the passphrase prompt as Enter passphrase (empty for no passphrase):. Nothing appears on screen while you type the passphrase; that is normal.

  • File location. Press Return for the default. Use a custom path such as ~/.ssh/id_ed25519_work only for separate keys, and point IdentityFile at it.
  • Overwrite (y/n)? appears if the file exists. Answer n unless you mean to replace a key: every service that trusts the old one would lock you out.
  • Passphrase. Recommended: it encrypts the key on disk, and the Keychain means you type it once. See passphrases.
  • Fingerprint. A short hash of the public key. GitHub shows the same value next to each key, so you can match them later. More in SSH key fingerprints.

The two files look like this:

$ cat ~/.ssh/id_ed25519.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICjC3B8SRdvp0H36PKIVoOSLOR8PA2GXw+6tRPH+FQ0z [email protected]

$ head -1 ~/.ssh/id_ed25519
-----BEGIN OPENSSH PRIVATE KEY-----

Ed25519 or RSA on a Mac

Use Ed25519. It is the default key type of current OpenSSH, its public key fits on one short line, and GitHub, GitLab, Bitbucket and every maintained server accept it. Create an RSA key, at 3072 or 4096 bits, only for a system that refuses Ed25519, such as an old network appliance. You can keep both side by side; the comparison is in Ed25519 vs RSA.

Store the passphrase in the macOS Keychain

Apple's OpenSSH has two additions that connect ssh-agent to the Keychain:

  • ssh-add --apple-use-keychain adds a key to the agent and saves its passphrase in the login Keychain.
  • UseKeychain yes in ~/.ssh/config makes ssh read the passphrase from the Keychain when it needs the key, and store it there when you type it at a prompt.

AddKeysToAgent yes is standard OpenSSH: the first time a key is used it goes into the agent, so later connections in the same login session need nothing. Together, the three mean you type the passphrase once, ever.

To check what the agent holds now:

$ ssh-add -l
256 SHA256:I2McFhOvOOgBGIf3aLmk0z7TTKxZoLZ32hK6Bxbk7Tw [email protected] (ED25519)

"The agent has no identities." is normal right after a restart; the key is loaded on first use. To load every key whose passphrase is in the Keychain right away, for example in a login script, run ssh-add --apple-load-keychain.

Order matters in ~/.ssh/config: for each option, the first value ssh finds wins. Put specific Host blocks first and the Host * defaults at the end of the file.

Copy the SSH public key to the clipboard (pbcopy)

pbcopy < ~/.ssh/id_ed25519.pub

The command prints nothing; the key is now on the clipboard. Paste it into the SSH keys page of GitHub, GitLab or a hosting panel. A correct public key is a single line of the form ssh-ed25519 AAAA... comment. If what you pasted starts with -----BEGIN, you copied the private key: delete it from wherever you pasted it.

For a server you can log in to with a password, skip the clipboard and let ssh-copy-id install it. Details, permissions and how to turn off password logins afterwards are in adding a key to a server.

Check that the key works

After adding the key to GitHub (step-by-step in SSH key for GitHub), test it:

$ ssh -T [email protected]
Hi your-username! You've successfully authenticated, but GitHub does not provide shell access.

For a server, ssh user@host should log you in without asking for the account password. If anything fails, ssh -v shows which keys were offered:

debug1: Offering public key: /Users/you/.ssh/id_ed25519 ED25519 SHA256:I2Mc... agent
debug1: Server accepts key: /Users/you/.ssh/id_ed25519 ED25519 SHA256:I2Mc... agent

Keys from the browser generator

You can also generate a key in your browser with the sshkeygen.dev generator. Its files land in Downloads, readable by other users. Move them and fix the permissions:

mkdir -p ~/.ssh && chmod 700 ~/.ssh
mv -i ~/Downloads/id_ed25519 ~/Downloads/id_ed25519.pub ~/.ssh/
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub

From there, continue with step 4 above.

Use multiple SSH keys with ~/.ssh/config

Separate keys for work and personal accounts, or for a customer's servers, are common. Create the second key under its own name:

ssh-keygen -t ed25519 -C "[email protected]" -f ~/.ssh/id_ed25519_work

Then give each host its own block in ~/.ssh/config. IdentitiesOnly yes stops ssh from offering every key in the agent, which can trip a server's limit of authentication attempts:

Host github-work
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519_work
  IdentitiesOnly yes

Host build
  HostName 203.0.113.20
  User deploy
  IdentityFile ~/.ssh/id_ed25519_work

Host *
  AddKeysToAgent yes
  UseKeychain yes
  IdentityFile ~/.ssh/id_ed25519

Then clone with git clone git@github-work:company/repo.git, and ssh build replaces the full address. Run ssh -G github-work to see the settings ssh would actually use for a host.

Troubleshooting

"Permissions 0644 for '~/.ssh/id_ed25519' are too open"

The full message is:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for '/Users/you/.ssh/id_ed25519' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.

ssh refuses a private key that other users can read. Run chmod 600 ~/.ssh/id_ed25519 and try again. The folder itself should be 700.

The passphrase is asked for after every restart

The key is in the agent but not in the Keychain configuration. Make sure ~/.ssh/config contains UseKeychain yes and AddKeysToAgent yes, and that you ran ssh-add --apple-use-keychain once.

"Permission denied (publickey)"

The server lacks your public key, or ssh offers a different one. Run ssh -v user@host and look for Offering public key. More causes in adding a key to a server.

"Bad configuration option: usekeychain"

You are running an OpenSSH that is not Apple's, for example one installed with Homebrew. Add IgnoreUnknown UseKeychain at the top of ~/.ssh/config, or call Apple's binary at /usr/bin/ssh. which ssh shows which one runs.

"Bad owner or permissions on /Users/you/.ssh/config"

The config file must belong to you and must not be writable by others. Fix it with chmod 600 ~/.ssh/config, and if it belongs to root because it was created with sudo, sudo chown "$USER" ~/.ssh/config.

"Could not open a connection to your authentication agent"

ssh-add cannot find the agent, usually because SSH_AUTH_SOCK is empty in this shell, for example inside tmux or after sudo. Open a new Terminal window, or start an agent for this shell with eval "$(ssh-agent -s)".

"sign_and_send_pubkey: signing failed ... agent refused operation"

The agent lists a key it can no longer use, often after the file was moved or its permissions changed. Run ssh-add -D to clear the agent, fix the permissions with chmod 600, and add the key again.

"Host key verification failed"

The server's host key does not match the one stored in ~/.ssh/known_hosts, or you answered no to the first-connection prompt. Confirm the new fingerprint with the server's owner, then remove the old entry with ssh-keygen -R host. The reasons are explained in SSH key fingerprints.

"no matching host key type found. Their offer: ssh-rsa"

The server is old and only offers an RSA host key signed with SHA-1, which current OpenSSH no longer accepts by default. Update the server if you can. If you cannot, allow it for that one host only:

Host old-router
  HostName 192.0.2.1
  HostKeyAlgorithms +ssh-rsa
  PubkeyAcceptedAlgorithms +ssh-rsa

FAQ

Where are SSH keys stored on a Mac?

In the hidden folder ~/.ssh, which is /Users/your-name/.ssh. Finder hides it; run open ~/.ssh in Terminal, or press Cmd + Shift + . in a Finder window to show hidden files.

Do I need Homebrew or any other software to create an SSH key on macOS?

No. ssh, ssh-keygen, ssh-agent, ssh-add and ssh-copy-id are part of macOS. A Homebrew OpenSSH works too, but it does not understand the Apple-only UseKeychain option.

Should I use ssh-add -K or --apple-use-keychain?

Use --apple-use-keychain on macOS 12 Monterey and later. -K was the old spelling; current versions print a deprecation warning for it. On Big Sur and older, -K is the only form that works.

Can I copy my SSH key to a new Mac?

You can copy both files into ~/.ssh on the new Mac and run chmod 600 on the private key. A separate key per computer is better practice: if one machine is lost, you remove only its public key from GitHub and your servers.

How do I show my public key on a Mac?

Run cat ~/.ssh/id_ed25519.pub, or pbcopy < ~/.ssh/id_ed25519.pub to put it on the clipboard. It is one line starting with ssh-ed25519. The file without .pub is the private key and is never shared.

Is it safe to keep the passphrase in the Keychain?

It is a reasonable trade-off. The login Keychain is encrypted with your account password, so a copied key file stays useless on its own. Anyone using your unlocked Mac can still use the key, so lock the screen when you step away.

How do I delete an SSH key on a Mac?

Remove its public key from GitHub and every server first, then run ssh-add -d ~/.ssh/id_ed25519 and delete both files. If the passphrase was stored, also delete the matching "SSH: /Users/you/.ssh/id_ed25519" entry in Keychain Access.