JCA design for RFC 7748

Adam Petcher adam.petcher at oracle.com
Thu Aug 10 13:44:53 UTC 2017


Anyone have any additional thoughts on this?

I think the most significant item we need to discuss is the extent to 
which JCA should allow curve parameters for RFC 7748/8032 to be 
specified over the API. Does anyone know of a particular use case (that 
we haven't discuss already) that would require a provider to support 
arbitrary curves? Any other arguments for or against this feature?


On 8/7/2017 4:37 PM, Adam Petcher wrote:
> I'm working on the Java implementation of RFC 7748 (Diffie-Hellman 
> with X25519 and X448). I know some of you have been anxious to talk 
> about how this would fit into JCA, and I appreciate your patience 
> while I learned enough about JCA and existing crypto implementations 
> to develop this API proposal. This API/design proposal is for RFC 7748 
> only, and it does not include the API for RFC 8032 (EdDSA). Of course, 
> I expect many of the decisions that we make for RFC 7748 will also 
> impact RFC 8032.
>
> First off, I think it is important to separate RFC 7748 from the 
> existing ECDH API and implementation. RFC 7748 is a different 
> standard, it uses different encodings and algorithms, and it has 
> different properties. Further, this separation will reduce the 
> probability of programming errors (e.g. accidentally interpreting a 
> Weierstrass point as an RFC 7748 point). So I propose that we use 
> distinct algorithm names for RFC 7748, and that we don't use any of 
> the existing EC classes like EllipticCurve and ECPoint with RFC 7748.
>
> We can achieve this separation without duplicating a lot of code if we 
> start with some simplifying assumptions. My goal is to remove 
> functionality that nobody needs in order to simplify the design and 
> API. If I am simplifying away something that you think you will need, 
> please let me know.
>
> A) We don't need to expose actual curve parameters over the API. 
> Curves can be specified using names (e.g. "X25519") or OIDs. The 
> underlying implementation will likely support arbitrary Montgomery 
> curves, but the JCA application will only be able to use the supported 
> named curves.
> B) We don't need direct interoperability between different providers 
> using opaque key representations. We can communicate with other 
> providers using X509/PKCS8 encoding, or by using KeyFactory and key 
> specs.
>
> These two assumptions greatly simplify the API. We won't need classes 
> that mirror ECParameterSpec, EllipticCurve, ECPoint, ECField, 
> ECPublicKey, etc. for X25519/X448.
>
> Now that the motivation and assumptions are out of the way, here is a 
> description of the proposed JCA API:
>
> 1) The string "XDH" will be used in getInstance() to refer to all 
> services related to RFC 7748 (KeyAgreement, KeyFactory, 
> KeyPairGenerator, etc). This is a departure from the ECDH API that 
> used "EC" for key generation (shared with ECDSA) and "ECDH" for 
> KeyAgreement, and makes the RFC 7748 API more like "DiffieHellman" and 
> other algorithms that use the same name for all services.
> 2) The new class java.security.spec.NamedParameterSpec (which 
> implements AlgorithmParameterSpec) will be used to specify curves for 
> RFC 7748. This class has a single String member which holds the name 
> of the curve ("X25519" or "X448"). This parameter spec class can be 
> reused by other crypto algorithms that similarly identify parameter 
> sets using names (e.g. FFDHE3072 in DiffieHellman). This new class can 
> be inserted into the hierarchy above ECGenParameterSpec.
> 3) There will be no classes in java.security.spec for EC public keys 
> and private keys. An RFC 7748 implementation can use the existing 
> classes X509EncodedKeySpec and PKCS8EncodedKeySpec for public and 
> private key specs, respectively.
> 4) There will be no interfaces in java.security.interfaces for RFC 
> 7748 public/private keys. Public/private key implementation classes 
> will implement java.security.PublicKey and java.security.PrivateKey, 
> which allows access to their encoded representations.
>
> Here is how the API will be implemented in the SunEC provider:
>
> 1) The public key and private key implementation classes will extend 
> sun.security.ec.X509Key and sun.security.ec.PKCS8Key, respectively. 
> This is similar to ECPublicKeyImpl and ECPrivateKeyImpl.
> 2) The KeyFactory for RFC 7748 will support translation to/from opaque 
> keys and X509EncodedKeySpec/PKCS8EncodedKeySpec.
>
> Example code:
>
> KeyPairGenerator kpg = KeyPairGenerator.getInstance("XDH");
> NamedParameterSpec paramSpec = new NamedParameterSpec("X25519");
> kpg.initialize(paramSpec); // equivalent to kpg.initialize(255)
> KeyPair kp = kpg.generateKeyPair();
>
> KeyFactory kf = KeyFactory.getInstance("XDH");
> X509EncodedKeySpec pubSpec = ...
> PublicKey pubKey = kf.generatePublic(pubSpec);
>
> KeyAgreement ka = KeyAgreement.getInstance("XDH");
> ka.init(kp.getPrivate());
> ka.doPhase(pubKey, true);
> byte[] secret = ka.generateSecret();
>
>
> One thing that is missing from the "core" API proposal is a way to 
> easily produce a public/private key from an encoded numeric value. Of 
> course, it's possible to put this value into a complete encoded 
> X509/PKCS8 key, but that is not very convenient. Perhaps we can add 
> another key spec class (that holds e.g. an AlgorithmParameterSpec and 
> a byte array) to make this easier, but I don't know how valuable this 
> would be.
>
> I appreciate any feedback the experts on the mailing list may have for 
> me. Please let me know what you think.
>
>




More information about the security-dev mailing list