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:
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.