RFR 8171279: Support X25519 and X448 in TLS 1.3
Xuelei Fan
xuelei.fan at oracle.com
Fri Sep 7 15:34:33 UTC 2018
Please let me know if you understand the following logic. Otherwise, I
will see if I could do something for you, maybe a prototype, maybe a
more detailed description. However, I may need more time for a
prototype/detailed description.
Per RFC 8446/7748, the X25519 key size is 32 bytes. Here we know the
key size. [1]
Per RFC 8446, the X25519 public key is encoded as byte string inputs and
outputs, as defined in RFC 7748. Her we know the encoding of the key. [2]
Suppose x25519 is used [3], then we know that the key sized per [1] and
the encoded key per [2]. Next step, let convert the encoded key bytes
to PublicKey.
EncodedKeySpec keySpec = ... // find a way to construct the keySpec
// at least, we can use:
// new EncodedKeySpec(byte[]);
// But please check if there's a better one
KeyFactory kFac = KeyFactory.getInstance("x25519");
// we know the name in [3]
PublicKey pubKey = kFac.generatePublic(keySpec);
Here you got the public key.
We may also need to generate the key pair.
KeyPairGenerator kpg = KeyPairGenerator.getInstance("x25519");
// we know the name in [3]
// may be optional, we know the name in [3].
NamedParameterSpec nps = new NamedParameterSpec("x25519");
kpg.initialize(nps);
KeyPair kp = kpg.generateKeyPair();
How you get the private key.
That's it. I know you may need to adjust the crypto implementation if
the provider does not support the above scenarios yet.
Xuelei
On 9/7/2018 7:30 AM, Adam Petcher wrote:
> On 9/7/2018 9:34 AM, Xuelei Fan wrote:
>
>> JSSE should use the 'x25519' name (via NamedParameterSpec object) only.
>
> This is the part that I don't know how to do. In JSSE, we convert
> between the array containing the encoded public key and the BigInteger
> representation of the public key used in XECPublicKeySpec. To do this,
> you need to know the length of the key, in bits. That means that JSSE
> needs to know the length of the key, in addition to the name, in order
> to do this conversion. I understand that there are lots of ways to get
> this information in JSSE, but I don't know which ways you would find
> acceptable.
>
> We keep going back and forth, saying the exact same things, and we don't
> seem to be making any progress. Can you please provide some code to
> illustrate what you want me to do? All I need is an acceptable
> implementation of the following method, that is used by JSSE to decode
> public keys:
>
> public static XECPublicKeySpec decodeXecPublicKey(byte[] key,
> NamedParameterSpec spec)
> throws InvalidParameterSpecException {
>
> XECParameters params = XECParameters.get(
> InvalidParameterSpecException::new, spec);
> BigInteger u = decodeXecPublicKey(key, params.getBits());
> return new XECPublicKeySpec(spec, u);
> }
>
> For reference, here is the implementation of the helper method that does
> the actual decoding, using the length.
>
> public static BigInteger decodeXecPublicKey(byte[] key,
> int bits) {
>
> ArrayUtil.reverse(key);
> // clear the extra bits
> int bitsMod8 = bits % 8;
> if (bitsMod8 != 0) {
> int mask = (1 << bitsMod8) - 1;
> key[0] &= mask;
> }
> return new BigInteger(1, key);
> }
>
>
More information about the security-dev
mailing list