⚠️ Note: Auto-translated Article
This page was generated by AI-assisted automatic translation from the original Japanese article.

Summary

Notes on the procedure for creating OpenSSH public/private key pairs on Linux and Windows.

2025-12-21 update: Reflects current OpenSSH/SSL library versions on recent OSes.

SSH Configuration Folder

This is where private keys, public keys, and other configuration files for client connections are stored by default.

OS Shell Config base folder (shell notation) Example
Linux bash ~/.ssh/ /home/USER1/.ssh/
Windows PowerShell ${env:USERPROFILE}\.ssh\ \Users\USER1\.ssh\

Supported Certificate Algorithms

The supported certificate algorithm formats differ depending on the OpenSSH/OpenSSL generation for each OS version (distribution).

OS/Version Release SSH Package SSL Library RSA ECDSA Ed25519
CentOS 3 2004 OpenSSH 3.6.1p2 OpenSSL 0.9.7a
CentOS 4 2005 OpenSSH 3.9p1 OpenSSL 0.9.7a
CentOS 5 2007 OpenSSH 4.3p2 OpenSSL 0.9.8e
CentOS 6 2011 OpenSSH 5.3p1 OpenSSL 1.0.1e
CentOS 7 2014 OpenSSH 7.4p1 OpenSSL 1.0.2k
CentOS 8 2019 OpenSSH 8.0p1 OpenSSL 1.1.1c
CentOS Stream 8 2020 OpenSSH 8.0p1 OpenSSL 1.1.1?
CentOS Stream 9 2021 OpenSSH 8.7p1 OpenSSL 3.0.?
CentOS Stream 10 2025 OpenSSH 9.9p1 OpenSSL 3.x.x
Rocky Linux 9 2021 OpenSSH 8.7p1 OpenSSL 3.x.x
Rocky Linux 10 2025 OpenSSH 9.9p1 OpenSSL 3.x.x
Windows Server 2019 (1809) 2018 OpenSSH 7.7p1 LibreSSL 2.6.5
Windows Server 2022 (21H2) 2022 OpenSSH 8.1p1 LibreSSL 3.0.2
Windows Server 2025 (24H2) 2024 OpenSSH 9.5p1 LibreSSL 3.3.6
Windows 10 (1803) 2018 OpenSSH 7.6p1 LibreSSL 2.6.4
Windows 10 (1809) 2018 OpenSSH 7.7p1 LibreSSL 2.6.5
Windows 10 (1903) 2019 OpenSSH 7.7p1 LibreSSL 2.6.5
Windows 10 (1909) 2019 OpenSSH 7.7p1 LibreSSL 2.6.5
Windows 10 (2009) 2020 OpenSSH 7.7p1 LibreSSL 2.6.5
Windows 10 (20H2) 2020 OpenSSH 7.7p1 LibreSSL 2.6.5
Windows 10 (21H1) 2021 OpenSSH 8.1p1 LibreSSL 3.0.2
Windows 10 (21H2) 2021 OpenSSH 8.1p1 LibreSSL 3.0.2
Windows 10 (22H2) 2022 OpenSSH 8.1p1 LibreSSL 3.0.2
Windows 11 (21H2) 2021 OpenSSH 8.1p1 LibreSSL 3.0.2
Windows 11 (22H2) 2022 OpenSSH 8.6p1 LibreSSL 3.4.3
Windows 11 (23H2) 2023 OpenSSH 9.5p1 LibreSSL 3.8.2
Windows 11 (24H2) 2024 OpenSSH 9.5p1 LibreSSL 3.8.2
Windows 11 (25H2) 2025 OpenSSH 9.5p2 LibreSSL 3.8.2
macOS 10.10 Yosemite 2014 OpenSSH 6.2p2 OSSLShim 0.9.8r
macOS 10.11 El Capitan 2015 OpenSSH 6.9p1 LibreSSL 2.1.7
macOS 10.12 Sierra 2016 OpenSSH 7.2p2 LibreSSL 2.4.1
macOS 10.13 High Sierra 2017 OpenSSH 7.7p1 LibreSSL 2.6.2
macOS 10.14 Mojave 2018 OpenSSH 7.9p1 LibreSSL 2.7.3
macOS 10.15 Catalina 2019 OpenSSH 8.1p1 LibreSSL 2.7.3
macOS 11.x Big Sur 2020 OpenSSH 8.1p1 LibreSSL 2.7.3
macOS 12.x Monterey 2021 OpenSSH 8.6p1 LibreSSL 2.8.3
macOS 13.x Ventura 2022 OpenSSH 9.0p1 LibreSSL 3.3.6
macOS 14.x Sonoma 2022 OpenSSH 9.6p1 LibreSSL 3.3.6
macOS 15.0–4 Sequoia 2024 OpenSSH 9.8p1 LibreSSL 3.3.6
macOS 15.5– Sequoia 2025 OpenSSH 9.9p2 LibreSSL 3.3.6
macOS 26.x– Tahoe 2025 OpenSSH 10.0p2 LibreSSL 3.3.6
  • All entries reflect the state after the latest updates have been applied
  • Recent CentOS/Rocky Linux versions appear to update the OpenSSL 3.x.y sub-version with minor upgrades
  • December 2025 note: Post-Quantum Cryptography (PQC) standardization and implementation is advancing in OpenSSH/SSL libraries. While available in some versions, it is unfortunately not yet mainstream. In particular, LibreSSL (common outside Linux) is lagging in PQC implementation, so as of now it appears usable only for Linux-to-Linux connections.

Choosing a Key Algorithm

Select the connection key algorithm in the following order of preference:

  1. Ed25519
  2. ECDSA (521-bit)
  3. RSA (SSH2-RSA 2048-bit or more)
  4. DSA (not recommended)

Available algorithms differ by OpenSSH/OpenSSL version. Ideally, create key pairs for all three — Ed25519, ECDSA, and RSA — on the client side, and use the highest-priority algorithm supported by the target server.

Creating Key Pairs

Commands to create RSA, ECDSA, and Ed25519 key pairs (private + public) in one shot.

With “creator’s username and hostname” as the comment, and no passphrase:

Linux OpenSSH (bash)

ssh-keygen -t ed25519 -q -N "" -C ${USER}@${HOSTNAME} -f ~/.ssh/id_ed25519
ssh-keygen -t ecdsa -b 521 -q -N "" -C ${USER}@${HOSTNAME} -f ~/.ssh/id_ecdsa
ssh-keygen -t rsa -b 2048 -q -N "" -C ${USER}@${HOSTNAME} -f ~/.ssh/id_rsa

Windows OpenSSH (PowerShell)

Specifying an “empty string” on the Windows command line requires special notation.

ssh-keygen -t ed25519 -q -N '""' -C "${env:USERNAME}@${env:COMPUTERNAME}" -f ${env:USERPROFILE}/.ssh/id_ed25519
ssh-keygen -t ecdsa -b 521 -q -N '""' -C "${env:USERNAME}@${env:COMPUTERNAME}" -f ${env:USERPROFILE}/.ssh/id_ecdsa
ssh-keygen -t rsa -b 2048 -q -N '""' -C "${env:USERNAME}@${env:COMPUTERNAME}" -f ${env:USERPROFILE}/.ssh/id_rsa

Registering the Public Key on the Target Server

To register a created key on the destination SSH server, append the contents of ./ssh/id_xxx.pub from the source to:

(home directory)/.ssh/authorized_keys

on the destination server. This is surprisingly tedious in practice, so the original OpenSSH package includes a dedicated script for it. If the authorized_keys file doesn’t exist, it will be created with correct permissions automatically.

Linux (CentOS 5/6) Client → Linux Server

REMOTEUSER=xxxx
REMOTEHOST=yyyy
ssh-copy-id -i ${HOME}/.ssh/id_ed25519.pub ${REMOTEUSER}@${REMOTEHOST}
ssh-copy-id -i ${HOME}/.ssh/id_ecdsa.pub ${REMOTEUSER}@${REMOTEHOST}
ssh-copy-id -i ${HOME}/.ssh/id_rsa.pub ${REMOTEUSER}@${REMOTEHOST}

Linux (CentOS 7/8) Client → Linux Server

OpenSSH shipped with CentOS 7 and later can suppress the (yes/no) fingerprint confirmation prompt.

REMOTEUSER=xxxx
REMOTEHOST=yyyy
ssh-copy-id -o StrictHostKeyChecking=no -i ${HOME}/.ssh/id_ed25519.pub ${REMOTEUSER}@${REMOTEHOST}
ssh-copy-id -o StrictHostKeyChecking=no -i ${HOME}/.ssh/id_ecdsa.pub ${REMOTEUSER}@${REMOTEHOST}
ssh-copy-id -o StrictHostKeyChecking=no -i ${HOME}/.ssh/id_rsa.pub ${REMOTEUSER}@${REMOTEHOST}

Windows OpenSSH Client → Linux Server

For Windows (SSH client) → Linux (SSH server):

Windows can’t use bash scripts like ssh-copy-id, so use a one-liner command instead.

$REMOTEUSER = "xxxx"
$REMOTEHOST = "yyyy"
Get-Content ${env:USERPROFILE}/.ssh/id_ed25519.pub | ssh ${REMOTEUSER}@${REMOTEHOST} "umask 077; test -d .ssh || mkdir .ssh ; cat >> .ssh/authorized_keys || exit 1"
Get-Content ${env:USERPROFILE}/.ssh/id_ecdsa.pub | ssh ${REMOTEUSER}@${REMOTEHOST} "umask 077; test -d .ssh || mkdir .ssh ; cat >> .ssh/authorized_keys || exit 1"
Get-Content ${env:USERPROFILE}/.ssh/id_rsa.pub | ssh ${REMOTEUSER}@${REMOTEHOST} "umask 077; test -d .ssh || mkdir .ssh ; cat >> .ssh/authorized_keys || exit 1"

※ Note: no error handling included

Connecting to a Windows sshd Target as Administrator

A public key must be registered in a special file.

${env:ProgramData}/ssh/administrators_authorized_keys

To register via GUI, open the file in Notepad with administrator privileges, then paste the key.

notepad ${env:ProgramData}/ssh/administrators_authorized_keys

Open Issues

  • Windows SSH client → Windows SSH server
  • Linux SSH client → Windows SSH server

A one-shot registration method like ssh-copy-id for these combinations is currently unknown.

It would probably be possible by installing PowerShell 7 on both sides and running PowerShell commands over a Remote-Session connection, but that feels like a case of the means becoming the end, so I’m not pursuing it further.