I'm trying to genereate RSA key to access somw git repositories in azure with ssh.
Having Ubuntu 22.04
and openssl version OpenSSL 3.0.2 15 Mar 2022
,
I generate RSA key like this:
$ ssh-keygen -t rsa -b 4096
Generating public/private rsa key pair.
Enter file in which to save the key (/home/me/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/me/.ssh/id_rsa
Your public key has been saved in /home/me/.ssh/id_rsa.pub
The key fingerprint is:
...
The keys randomart image is:
+---[RSA 4096]----+
....
....
+----[SHA256]-----+
But when I do
$ cat ~/.ssh/id_rsa
, I see my key file start with
-----BEGIN OPENSSH PRIVATE KEY-----
Should it be BEGIN RSA PRIVATE KEY
instead? What is the difference?
Should it be
No, not really. The only "should" is that it should be a format that ssh
itself understands. (The private key is never sent to the server, so there's no question about compatibility with Azure it only has to be compatible with your client.) So the key format that you currently have is correct; if your ssh-keygen produced it, then your ssh client will be able to use it.
There's no standard format for storing SSH private keys in files; each SSH client might use its own and in practice there are probably 4 or 5 different formats out there. Previously OpenSSH (the ssh
program) just happened to use the PKCS#1 format because the OpenSSL library already used the same format for its own private keys and provided a convenient function for loading and storing keys in this format.
However, OpenSSH doesn't want to depend on OpenSSL after all, SSH itself isn't based on SSL/TLS in any way; the only reason OpenSSH is using OpenSSL at all is for its cryptography functions (libcrypto, e.g. RSA or AES) so it ended up creating its own private key format, initially just for Ed25519 keys, but eventually began using it for all algorithms. (Although it still understands the old format.)
Note that the actual "keys" (e.g. RSA primes, or EC points) still work the same way regardless of file format, so if needed you can easily convert from one format to another (using ssh-keygen -p -m
or PuTTY's puttygen
tools).
What is the difference?
PKCS#1 key files (BEGIN RSA PRIVATE KEY
) come from the PEM encrypted messaging project. The format is fairly outdated, e.g. it's weak against passphrase bruteforcing. Even OpenSSL itself later started using a newer PKCS#8 format (which uses BEGIN PRIVATE KEY
or BEGIN ENCRYPTED PRIVATE KEY
headers) for all new private keys.
However, both PKCS#1 and PKCS#8 formats internally use ASN.1, which is a rather complex data serialization method for TLS software that's still acceptable, because they already need ASN.1 support to parse TLS certificates anyway, but for SSH clients it just brings another unnecessary dependency on OpenSSL.
In addition, their development is also primarily driven by TLS and X.509 certificates, which is a different world from SSH for example, when OpenSSH first got support for Ed25519 keys, it couldn't use OpenSSL's existing functions to store them, because that algorithm hadn't been adopted by the TLS world yet; an algorithm ID hadn't been assigned, the data format hadn't been agreed to.
So as a result, OpenSSH created its own format for storing private keys (the one with BEGIN OPENSSH PRIVATE KEY
headers), which uses the same structures and algorithm identifiers as SSH itself does, meaning that any keys that SSH supports can be stored in the OpenSSH key format and they can be loaded/stored without relying on a SSL/TLS library any longer.
(PuTTY also has its own "PPK" key format for a similar reason of avoiding complex external libraries.)