JCA design for RFC 7748

Michael StJohns mstjohns at comcast.net
Wed Aug 16 19:17:32 UTC 2017


On 8/16/2017 11:18 AM, Adam Petcher wrote:
> On 8/15/2017 7:05 PM, Michael StJohns wrote:
>> On 8/15/2017 1:43 PM, Xuelei Fan wrote:
>>> On 8/11/2017 7:57 AM, Adam Petcher wrote:
>>>>
>>>> I'm also coming to the conclusion that using X.509 encoding for 
>>>> this sort of interoperability is too onerous, and we should come up 
>>>> with something better. Maybe we should add a new general-purpose 
>>>> interface that exposes some structure in an algorithm-independent 
>>>> way. Something like this:
>>>>
>>>> package java.security.interfaces;
>>>> public interface ByteArrayValue {
>>>>
>>>>      String getAlgorithm();
>>>>      AlgorithmParameterSpec getParams();
>>>>      byte[] getValue();
>>>> }
>>>>
>>> I'm not sure how to use the above interface in an application.
>>
>> This is sort of the moral equivalent of using the TXT RR record in 
>> DNS and the arguments are similar.
>>
>> This is a bad idea.
>
> I'm not a DNS expert, so I apologize in advance if I misunderstood 
> your argument. What I think you are saying is that it is bad to store 
> something in a string or byte array which has no semantics, and it is 
> better to store information in a more structured way that has a clear 
> semantics. I agree with this.


>
> My intention with this ByteArrayValue is to only use it for 
> information that has a clear semantics when represented as a byte 
> array, and a byte array is a convenient and appropriate representation 
> for the algorithms involved (so there isn't a lot of unnecessary 
> conversion). This is the case for public/private keys in RFC 7748/8032:
>
> 1) RFC 8032: "An EdDSA private key is a b-bit string k." "The EdDSA 
> public key is ENC(A)." (ENC is a function from integers to 
> little-endian bit strings.
> 2) RFC 7748: "Alice generates 32 random bytes in a[0] to a[31] and 
> transmits K_A =X25519(a, 9) to Bob..." The X25519 and X448 functions, 
> as described in the RFC, take bit strings as input and produce bit 
> strings as output.

Thanks for making my point for me.  The internal representation of the 
public point is an integer.  It's only when encoding or decoding that it 
gets externally represented as an array of bytes.  (And yes, I 
understand that the RFC defines an algorithm using little endian byte 
array representations of the integers - but that's the implementation's 
call, not the API).

With respect to the output of the KeyAgreement algorithm - your (2) 
above, the transmission representation (e.g. the encoded public key) is 
little endian byte array representation of an integer.  The internal 
representation is - wait for it - integer.

I have no problems at all with any given implementation using little 
endian math internally.  For the purposes of using JCA, stick with 
BigInteger to represent your integers.  Use your provider encoding 
methods to translate between what the math is internally and what the 
bits are externally if necessary.  Implement the conversion methods for 
the factory and for dealing with the existing EC classes.   Maybe get 
BigInteger to be extended to handle (natively) littleEndian 
representation (as well as fixed length outputs necessary for things 
like ECDH).






>
> So I think that a byte array is the correct representation for 
> public/private keys in these two RFCs.

Nope.

>
>>
>>>
>>> I don't worry about this issue any more.  At present, each 
>>> java.security.Key has three characters (see the API Java doc):
>>> . an algorithm
>>> . an encoded form
>>> . a format
>>>
>>> The format could be "X.509", and could be "RAW" (like 
>>> ByteArrayValue.getValue()).  I would suggest have the named curve in 
>>> the algorithm characters, and use "RAW" as the encode format.
>>> If X.509 encoding is required, KeyFactory.getKeySpec​() could do it.
>> Um... I think that doesn't make a lot of sense.  The default contract 
>> for public keys is X.509 and the default for private keys is PKCS#8.  
>> Almost all uses of the encoded formats are related to PKIX related 
>> functions.   (See for info the javadoc for PublicKey).
>
> I'm concerned about this, too. Ideally, we want PKI code to handle 
> these new keys without modification. The javadoc wording makes it a 
> little unclear whether public keys *must* use X.509 encoding, but 
> using other encodings for public keys would probably be surprising.

There's two different things going on here - many encodings (e.g. for EC 
public keys there's the fixed length X and fixed length Y byte array big 
endian big integer as well as the X.92 representation indicating both 
compressed and uncompressed points and then the wrapping of those in 
SubjectPublicKeyInfo then there's the raw signature vs the ASN1 SEQUENCE 
OF INTEGER version.)  JCA uses the X.509 stuff quite a bit to deal with 
all of the CertificatePathValidation  and Certificate validation 
things.  But the "rawer" stuff such as DH sometimes uses bare points 
with the curve being understood by context (see for example the Javacard 
KeyAgreement classes).

In the current case, we still need a way to "sign" and "carry" the new 
public points and to be as interoperable with all of the "old" stuff.  I 
guess you could come up with a whole new set of ideas in this space, but 
you would be hated both by the implementers and the folks that actually 
had to try and use it.

If you were just going to use this for crypto protocols (TLS and IPSEC) 
I might agree that X.509 wasn't necessary - but I don't think you want 
to say that either.

>
>>
>> To be JCA compliant you need all of: <snip>
>>
> Are you describing hard compliance requirements or more informal 
> expectations? If it's the former, where are these requirements 
> documented?
>

AFAICT this is implicit in the way the JCA is structured.  A given set 
of key classes is supposed to be able to be converted and used for all 
appropriate APIs (Signature, KeyAgreement, Cipher, KeyPair, 
KeyPairGenerator, KeyFactory etc) and all of those classes I mentioned 
appear to be necessary to ensure this is possible.

Happy to have an argument against that point of view.

Mike





More information about the security-dev mailing list