Skip to the content.

Passwordless SSH Key Authentication

SSH public-key authentication lets you log into a Linux machine without entering the account password each time. Instead, your computer proves that it possesses a private cryptographic key corresponding to a public key installed on the remote machine.

Objectives

What are SSH keys?

An SSH key pair consists of:

Modern OpenSSH keys are normally stored as text files containing encoded cryptographic data.

A modern Ed25519 public key looks roughly like:

ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAbCdEfGhIjKlMnOpQrStUvWxYz... name+2026@host.com

An OpenSSH private key looks roughly like:

-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAA...
...
-----END OPENSSH PRIVATE KEY-----

The public key can safely be copied to a server. The private key must remain private.

The text after the public key is a comment. It is normally used to identify the key and does not form part of the cryptographic key itself.

Why use keys instead of passwords?

SSH keys are more convenient because they allow login without repeatedly typing a password, and more secure because authentication is based on a cryptographic key rather than a password that can be guessed.

A useful mental model

Basic points:

flowchart LR
    A["Your computer"] --> B[("Private key (kept secret), ~/.ssh/keyfile")]  
    B --> C["ssh-agent"]
    A --> D
    C --> D["SSH client"]
    D -->|SSH connection| E["Remote server/Pi"]
    E --> F[("~/.ssh/authorized_keys")]
    F --> G["Public key"]

The important distinction is:

Private key
    = proves that you are the owner of the key

Public key
    = installed on the server to identify the corresponding private key

The server never needs your private key.

The confusing part of SSH

The cryptography isn’t usually the difficult part of SSH.

The difficult part is remembering where SSH expects its keys, configuration files, and authentication settings to be located.

The normal per-user SSH directory is:

~/.ssh/

Typical files include:

~/.ssh/config
~/.ssh/authorized_keys
~/.ssh/id_ed25519
~/.ssh/id_ed25519.pub

The exact key filenames can be changed, which is useful when managing multiple keys.

On Windows, the equivalent directory is normally:

C:\Users\YourName\.ssh\

SSH client on Linux and Raspberry Pi OS

OpenSSH is the standard SSH implementation on Linux, and the SSH client is commonly installed.

The SSH server, however, is normally disabled by default on a fresh Raspberry Pi OS (Raspbian) installation. There are several ways to enable it:

Enable SSH while preparing the SD card

When using Raspberry Pi Imager, configure the OS during the imaging process and enable SSH under the remote-access/SSH options.

You can also configure your public SSH key at this point, allowing the Pi to be ready for passwordless SSH on its first boot. This is particularly useful for a headless Pi: no monitor or keyboard is required just to enable SSH after installation.

Enable SSH after installation

If SSH has not already been enabled:

sudo raspi-config

Then select:

Interface Options
    SSH

Alternatively, on current Raspberry Pi OS installations, SSH can be enabled from the desktop configuration tools.

The distinction to remember is:

ssh     = SSH client
sshd    = SSH server

The client is what you use to connect to another machine. The server is what allows another machine to connect to you.

Microsoft OpenSSH client on Windows

Modern Windows includes Microsoft’s OpenSSH client.

From PowerShell:

ssh -V

You should see something similar to:

OpenSSH_for_Windows_9.xp1, LibreSSL ...

You can find which ssh.exe Windows is using with:

where.exe ssh

Typically it will be:

C:\Windows\System32\OpenSSH\ssh.exe

Windows OpenSSH includes:

ssh
ssh-keygen
ssh-agent
ssh-add
scp
sftp

Generate an SSH key pair (client)

Windows and Linux use the same ssh-keygen command:

ssh-keygen -t ed25519 -C "name+2026@host.com"

The -t ed25519 option specifies the key type. The -C option adds a comment to the public key. Using the same value as the key filename makes it easy to identify the key later.

For simplicity, I assume a blank passphrase.

When ssh-keygen asks where to save the key, enter the filename you want. For example:

Windows:

C:\Users\YourName\.ssh\name+2026@host.com

Linux:

/home/pi/.ssh/name+2026@host.com

This creates two files:

Where are the keys normally stored?

If you accept ssh-keygen’s default location, keys are normally stored in:

Windows: C:\Users\YourName\.ssh\ Linux: ~/.ssh/

The filename you specify becomes the base filename for both keys. If the .ssh directory does not already exist, ssh-keygen will normally create it when you use its default location.

Importing an existing key pair

If you already have an SSH key pair, you do not need to generate another one.

The keys are files. For example:

name+2026@host.com
name+2026@host.com.pub

can simply be copied into the appropriate .ssh directory (C:\Users\YourName\.ssh\ on Windows, ~/.ssh/ on Linux).

For example:

cp /somewhere/name+2026@host.com ~/.ssh/
cp /somewhere/name+2026@host.com.pub ~/.ssh/

Then protect the private key:

chmod 600 ~/.ssh/name+2026@host.com
chmod 644 ~/.ssh/name+2026@host.com.pub

You can also copy and paste the text of the keys directly between machines. Never copy the private key to a server merely because the server needs to authorize your access. Normally, only the public key belongs on the server.

Configure the server to authorize with your public key

For a normal Linux user, SSH public keys that are permitted to log in are normally stored in:

/home/pi/.ssh/authorized_keys

Each authorized public key occupies one line.

Copying a public key from Windows to the server

Open the .pub file in Windows Notepad. Copy the entire line, beginning with ssh-ed25519 and ending with the comment.

SSH into the Raspberry Pi using your existing password authentication.

Then:

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

Paste the public key as a single line. Save the file (Ctrl+O, Ctrl-X in nano/pico).

Then:

chmod 600 ~/.ssh/authorized_keys

If the file already contains other authorized keys, do not overwrite them. Add the new public key on another line. Check the file with cat ~/.ssh/authorized_keys.

Copying a public key automatically

Linux systems commonly provide ssh-copy-id, which can install your public key on a remote Linux machine.

ssh-copy-id -i ~/.ssh/name+2026@host.com.pub pi@raspberrypi

You will normally need to enter the Pi’s password once.

Using an SSH agent

The SSH agent handles key management, authentication, and more. It enables login without having to specify the private key each time.

Windows

Enable and start the agent in PowerShell:

Set-Service -Name ssh-agent -StartupType Automatic
Start-Service ssh-agent

Check if your key is loaded:

ssh-add -l

If not, add it:

ssh-add ~/.ssh/name+2026@host.com

Linux (including WSL)

Linux provides ssh-agent and ssh-add. Many desktop environments provide their own keyring/agent integration. If ssh-add -l works when you open a terminal, you already have an agent.

Otherwise, add this to your shell config (e.g. ~/.bashrc or ~/.zshrc):

# Start an SSH agent if one isn't already available.
if [ -z "$SSH_AUTH_SOCK" ]; then
    eval "$(ssh-agent -s)" >/dev/null
fi

# Load my SSH key into the agent.
ssh-add ~/.ssh/name+2026@host.com 2>/dev/null

WSL

WSL does not automatically provide the Windows desktop-style SSH-agent/keyring integration. The above .bashrc configuration is common in WSL. WSL can also be configured to use the Windows SSH agent, but that is a different arrangement.

Testing and usage

Test passwordless login

Once the public key is in the Raspberry Pi’s authorized_keys and the private key is loaded into the agent, try:

ssh pi@raspberrypi

If everything is configured correctly, SSH should authenticate using the key instead of asking for the Pi account password.

If not using an agent: use -i

You can explicitly tell SSH which private key to use with -i.

Windows:

ssh -i "$HOME\.ssh\name+2026@host.com" pi@raspberrypi

Linux:

ssh -i ~/.ssh/name+2026@raspberrypi pi@raspberrypi

The -i option means identity file. It tells SSH to use that particular private key.

Agent-less SSH configuration

When using keys without an agent, you can create an SSH configuration file to avoid repeatedly specifying the key path.

Create: ~/.ssh/config

Host raspberrypi
    HostName 192.168.1.50
    User pi
    IdentityFile ~/.ssh/name+2026@raspberrypi

Then simply:

ssh raspberrypi

Advanced Topics

Windows IDEs and Remote SSH

Windows IDEs such as Zed and Visual Studio Code default to using Microsoft’s OpenSSH client for Remote-SSH connections. This means they can use the same keys and SSH configuration used by PowerShell.

You can check which OpenSSH executable is being used from PowerShell with where.exe ssh.

PuTTY and PuTTYgen

PuTTY uses its own key format (.ppk) and key-management tools rather than Microsoft’s OpenSSH format by default. PuTTYgen can import existing private keys and save them as .ppk files.

PuTTY provides Pageant, an SSH authentication agent. You can load a .ppk private key into Pageant, after which PuTTY sessions can use the key without repeatedly asking for the passphrase.

Key management

Remove a key from the SSH agent

Windows:

ssh-add -d "$HOME\.ssh\name+2026@host.com"

Linux:

ssh-add -d ~/.ssh/name+2026@raspberrypi

To remove all keys from the agent: ssh-add -D. This removes the identities from the running agent; it does not delete the private-key files.

Using a naming convention such as name+2026@host.com makes key management much easier when you accumulate multiple machines and services.

Retiring a key means:

  1. Remove its public key from authorized_keys on servers.
  2. Remove/revoke it from services such as GitHub.
  3. Remove it from SSH agents with ssh-add -d, or clear the agent with ssh-add -D.
  4. Remove the private key from machines where it is no longer needed.

Quick Reference