Search code examples
javacryptographyopensshpkcs#8

How to read an OpenSSH or OpenSSL private key natively in Java?


I'd like to read an OpenSSL private key natively in Java, without using BouncyCastle.

I have searched far and wide for this, but I cannot find an answer. When you see a key like:

-----BEGIN EC PRIVATE KEY-----
...base64 here....
-----END EC PRIVATE KEY-----

What format is that? It appears to be the same encoding as OpenSSH keys (I think). It is not pkcs8, although OpenSSL allows you convert it's key format to pkcs8 using the pkcs8 command with -topk8 argument.

I certainly cannot be the only person that has run into this problem, but despite extensive searching, I cannot find an answer. Thanks!

EDIT: None of the duplicates that were suggested talk about using a pure-java solution (no openssl) and no Bouncy Castle. Please don't mark it as a duplicate unless this exact question has been asked.

It's easy for western developers to be ignorant of the way business is conducted in Asian countries. China, as an example, has an entire set of EC curves that are unheard of in OpenSSL and Bouncycastle, that are used in inter-business-commerce, so the two two tools: OpenSSL and Bouncycastle are either very old versions or not available at all. Answers like "just use openssl" are neither helpful nor constructive.


Solution

  • https://www.rfc-editor.org/rfc/rfc5915

    1. Elliptic Curve Private Key Format

    This section gives the syntax for an EC private key. Computationally, an EC private key is an unsigned integer, but for representation, EC private key information SHALL have ASN.1 type ECPrivateKey:

    ECPrivateKey ::= SEQUENCE {
     version        INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
     privateKey     OCTET STRING,
     parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
     publicKey  [1] BIT STRING OPTIONAL
    }