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