To work with ECDSA keys I am using the python-ecdsa library. Unfortunately this library can not process keyfiles properly if they are provided in the OpenSSH format. Instead I generate them in the PEM format, which the library can handle, using the following command:

ssh-keygen -t ecdsa -b 256 -f /home/user/Documents/ECDSA/key -m pem

However, while I am able to work with the keyfiles in PEM just fine, I do need them in the OpenSSH format in the end. The following ideas come to mind:

  1. Generate them in the OpenSSH format and convert them to the PEM format.
  2. Generate them in the PEM format and convert them to the OpenSSH format.
  3. Generate them in both formats in one go?

Is any of these options possible? I am aware one can convert formats when the type is RSA like so:

ssh-keygen -f id_rsa.pub -m 'PEM' -e > public.pem

However for ECDSA that is not possible:

do_convert_to_pem: unsupported key type ECDSA

What options do I have?


Which key(s) are you trying to use with that library -- private or public, which that library calls Signing and Verifying -- or both?

ssh-keygen -t ecdsa -b $n -m pem (in OpenSSH 7.8 up) with empty password generates the private key file in OpenSSL-compatible unencrypted format (with header -----BEGIN EC PRIVATE KEY-----) which that library wants; it generates the public key file in OpenSSH's own format which is completely unlike anything OpenSSL uses or that library wants. If you (mistakenly?) generate (or convert) the private key file in OpenSSH 'new' format (default since 7.8 and before that -o, with header -----BEGIN OPENSSH PRIVATE KEY----) you can convert it to OpenSSL form by 'changing' the password (possibly from empty, definitely to empty) with ssh-keygen -p -m pem [-f file] (but NOT -e). You can use -P old and -N new on the commandline if you don't want to be prompted for the passwords.

ssh-keygen -e [-m various] operates on the public key, in either OpenSSH format or several other formats. In particular -m pem for a public key means an RSA-only format defined by PKCS1 and used by OpenSSL briefly long long ago. OpenSSL in this century uses the generic format defined by X.509 "SubjectPublicKeyInfo", more conveniently available in rfc 5280 and for ECDSA specifically rfc 5480, which currently works for RSA DSA and ECDSA though not Ed25519, and which ssh-keygen bizarrely calls -m pkcs8 even though PKCS8 is actually a quite different standard for private keys. (Recent versions of OpenSSH discourage use of DSA in SSH, but as of now ssh-keygen still supports keys for it.)

Cross-similar https://superuser.com/questions/1470852/differences-between-ssh-keygen-private-keys-and-libressls and https://stackoverflow.com/questions/55733451/what-is-the-difference-between-rsa-private-key-with-headers-and-openssh-private and more

| improve this answer | |

OpenSSH private keys are stored in PEM format.

OpenSSH public keys contain the key in PEM format, but without the -----Begin EC Public Key----- header and footer.

See this question for an explanation of OpenSSH key formats: https://superuser.com/questions/1477472/openssh-public-key-file-format

| improve this answer | |
  • 1
    OpenSSH 7.8 up by default uses its own format for private keys; although also a PEM format this is not compatible with OpenSSL or the indicated library. Generating with -m pem fixes that. The OpenSSH public key format is NOT PEM, and although it is base64, as your own link describes, the data format encoded by that base64 is not the same as used in the PEM files used in OpenSSL and that library. – dave_thompson_085 Sep 18 '19 at 7:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.