"Pluggable" key serialization in JCE/JCA
Anthony Scarpino
anthony.scarpino at oracle.com
Fri Mar 25 16:12:40 UTC 2022
When you say "construct and EC key", do you mean creating an EC key from
an existing set of values via PKCS8 or X509 encoding? Or are you
talking about EC key generation?
Tony
On 3/25/22 1:03 AM, Anders Rundgren wrote:
> Hi Mike & the JDK crypto team,
>
> What I'm saying is that key serialization in Java haven't gotten enough
> attention. Examples:
>
> AFAIK, there is still no support for using named curves to construct an
> EC key. Names curves are MANDATORY in JOSE/CODE.
>
> The gap between EdDSA keys as expressed in JOSE/COSE and the Java API is
> simply put GIGANTIC:
> https://mail.openjdk.java.net/pipermail/security-dev/2020-August/022379.html
>
> The only obvious solution is rolling your own:
> https://github.com/cyberphone/openkeystore/blob/master/library/src/org/webpki/crypto/OkpSupport.java
>
> This code [probably] stinks but it is hardly my fault...
>
> The JDK crypto team is the only party who can clean up this mess.
>
> Since importing X.509 certificates through PKCS12/KeyStore works out of
> the box without any a prior knowledge of key algorithms, there is
> already a precedent. It is almost just copy and paste :)
>
> The new crypto systems that are on the way in (BLS, Post Quantum),
> accentuates this issue.
>
> Regarding HSMs, I gave it one more thought and I didn't come up with any
> connections except maybe in Keytool but HSMs appear to be X.509-oriented
> which not the case with COSE/JOSE.
>
> Regards,
> Anders
>
> On 2022-03-25 3:12, Michael StJohns wrote:
>> On 3/24/2022 12:28 PM, Anders Rundgren wrote:
>>> On 2022-03-24 16:59, Michael StJohns wrote:
>>>> On 3/24/2022 2:46 AM, Anders Rundgren wrote:
>>>>> Hi List,
>>>>>
>>>>> I find it a bit strange that every user of crypto either have to write
>>>>> or install specific software for converting JOSE/COSE/PEM keys
>>>>> back-and-forth to Java's internal representation. This reduces the
>>>>> value of the abstract types as well.
>>>>>
>>>>> Now there is whole bunch of new algorithms coming to the Java platform
>>>>> making this task even less attractive.
>>>>>
>>>>> So my question is simply: How about including this part in an enhanced
>>>>> JCE/JCA? That is, making the encoder/decoder "pluggable" and hiding
>>>>> this complexity from users and library developers?
>>>>
>>>> Hi Anders -
>>>
>>> Hi Mike,
>>>
>>>>
>>>> Isn't that the exact purpose for KeyFactory and its plugins?
>>>
>>> They presume that you know not only the key algorithm but the
>>> associated parameters as well. Why should users or library developers
>>> have to deal with that?
>>
>> Um - no. They presume you know the key algorithm, but (using EC Public
>> keys for example), you can use either of the X509PublicKeySpec (to
>> decode an encoded key), or the ECPublicKeySpec (to deal with building a
>> key from scratch using the parameters. You can notionally (haven't
>> tried it, but should work) use KeyFactory.getKeySpec() to convert
>> between the two formats or use Key.getEncoded() to get the default
>> encoding for the key.
>>
>> The equivalent on the ECPrivateKey side are the ECPrivateKeySpec and
>> PKCS8EncodedKeySpec clases.
>>
>> PEM is actually not an encoding, but a wrapping of an encoding. The only
>> part of Java that deals with it natively (I believe) is the
>> CertificateFactory for X.509 certificates. You may have an extra step
>> to add or remove a PEM style envelope (or the equivalent BASE64 bare
>> string), but that's reasonable.
>>
>>>
>>> The requirement to know key algorithm in advance forces you into ASN.1
>>> decoding for dealing with PEMs. Been there done that.
>>
>> Ah - not sure why you wouldn't know the key algorithm, BUT: It should
>> theoretically be possible to write a KeyFactory provider that does that
>> decoding for you from the X509PublicKeySpec (or PKCS8PrivateKeySpec) and
>> returns an appropriate PublicKey. Check the actual return type to figure
>> out what type of key. E.g.:
>>
>> KeyFactory kf = KeyFactory.getInstance("GenericDecoder");
>>
>> As I said below, you'll need to define the equivalent opaque format
>> KeySpec classes to handle COSE and JOSE. I think that's a class per
>> type of encoding.
>>
>>>
>>>>
>>>> You might need to add KeySpec types for Jose and Cose
>>>> (JOSEEncodedKeySpec and COSEEncodedKeySpec) assuming both of those
>>>> cover
>>>> all of the secret, public and private key specifications.
>>>>
>>>> Or hmm... GenericEncodedKeySpec (String alg, byte[] encoded key) or
>>>> GenericEncodedKeySpec (String alg, String encodedKey).
>>>>
>>>>
>>>>>
>>>>> Eventually you could end up with something like:
>>>>>
>>>>> PrivateKey privateKey = new KeyConverter().readPrivateKey(byte[] or
>>>>> stream);
>>>>>
>>>>> You would not even have to know in which format the key is supplied in
>>>>> since this could be accomplished by simple "sniffing".
>>>>
>>>> Nope. This isn't safe as someone might up with yet another
>>>> representation that looks like one of the "sniffable" ones. You could
>>>> build a private implementation that takes its best shot, but ....
>>>
>>> Finding out if the container is COSE, JOSE, or PEM is (AFAICT)
>>> trivial. If the guess is incorrect a properly designed decoder should
>>> simply fail.
>>
>> It's trivial NOW because its a closed set of possibilities. And even
>> then, you're assuming you don't have to detect ASN1 vs raw key encodings
>> vs string encodings. Simply detecting a) whether a file is character,
>> b) detecting the character encoding, and c) accidentally thinking a
>> character file is actually binary or vice versa is fragile.
>>
>> The addition of the "new" EC variant keys required a substantial
>> reworking of the API to support them and the arguments were fierce. The
>> additions were not free.
>>
>> I deal with no fewer than 3 encodings for an EC public key. Two or
>> three for an EC private key. 2 or 3 text versions of a RSA public key
>> along with the X509Encoded binary version and the TPM binary version.
>> Etc. I usually know what type of key I'm dealing with when I get it,
>> but I would love a magic DWIM class that did the right thing on all
>> inputs.
>>
>>
>>>
>>>>
>>>>>
>>>>> To make "pluggability" feasible, I'm trying to convince the JOSE/COSE
>>>>> folks to give each new crypto system a separate namespace as an
>>>>> alternative to overloading OKP (RFC 8037), even if the parameters
>>>>> match technically. AFAICT, X.509 public keys essentially already
>>>>> adhere to this notion.
>>>>>
>>>>> I would exclude private key import and export in HSMs since these are
>>>>> specific and rare occasions.
>>>>
>>>> Again, no. Don't do this in an incomplete way - it will come back to
>>>> bite you. You don't have to implement the plugin that talks to the
>>>> HSM,
>>>> but you have to define the mechanism/API so that the HSM vendors don't
>>>> curse your first born child later.
>>>
>>>
>>> This is little bit out of my league but targeting the masses is core.
>>
>> This is the problem with open source some times. It may be core, but it
>> is not complete and leaving this as a problem to be worked later is a
>> bit unprofessional.
>>
>> I don't mean any offense here, but there's a problem with basing
>> everything what IOT requires and ignoring everything else.
>>
>> Later, Mike
>>
>>
>>>
>>>
>>> Anders
>>>
>>>>
>>>> Mike
>>>>
>>>>
>>>>>
>>>>> WDYT?
>>>>>
>>>>> Thanx,
>>>>> Anders
>>>>
>>>>
>>>
>>
>
More information about the security-dev
mailing list