-1

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.

SQB
  • 3,926
  • 2
  • 28
  • 49
Jonathan S. Fisher
  • 8,189
  • 6
  • 46
  • 84

2 Answers2

2

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
}
Community
  • 1
  • 1
bartonjs
  • 30,352
  • 2
  • 71
  • 111
1

The Base64-block between the Begin- and End-blocks is the ASN.1 encoded private key data in the format bartonjs described in his answer. Without libraries that take the work from you, you have to do the loading yourself. An example how to do that for RSA can e.g. be found here. Other formats can be loaded in a similar way by passing the corresponding algorithm name to KeyFactory.getInstance(...);. In order to do this you have to parse the text at the begin-block and do a mapping from the name there to the algorithm-name to be used for the creation of the factory (most should be the same as being provided in the block, but I'm not sure for elliptic curves that is used in the example your provided in your question).

The base64-block needs to be decoded to a byte-array to pass it to the KeySpec.

Lothar
  • 5,323
  • 1
  • 11
  • 27