JCA design for RFC 7748
Anders Rundgren
anders.rundgren.net at gmail.com
Tue Aug 15 21:29:03 UTC 2017
Does this mean that the following is correct?
EC public key:
public interface ECPublicKey
extends PublicKey, ECKey
CFRG/RFC 7748 public key:
public class TheActualImplememtationClass
extends PublicKey, ByteArrayKey
If so, it should work. Documentation seems a bit less obvious though
which is why I advocated a more direct approach.
Cheers,
Anders
On 2017-08-15 17:06, Adam Petcher wrote:
> Okay, let me go back to the beginning with some slightly weaker
> assumptions, and a slightly modified design. I've attempted to
> incorporate all the feedback I've received so far, but if you feel like
> I missed something, please let me know.
>
> Assumptions:
>
> A) We don't need to expose curve domain parameters over the API in the
> initial design/implementation. 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. Support for arbitrary curve
> parameters in the API is something that can be considered as a separate
> feature in the future.
> B) We don't need specs and interfaces that are specific to RFC 7748
> public/private keys. To allow interoperability between providers, and to
> make it easy to specify key values, we can use more general purpose spec
> classes and interfaces that can be reused by multiple algorithms. In
> particular, we should be able to reuse these interfaces/classes between
> RFC 7748 and RFC 8032.
>
> Here is a high-level description of the proposed JCA API. A more
> detailed description will be provided during the JEP review.
>
> 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 specific to RFC 7748
> public keys and private keys. A new class called ByteArrayKeySpec will
> be added to java.security.spec. This class will hold an algorithm name
> String, an AlgorithmParameterSpec, and a byte array containing the raw
> key bytes. This class is suitable for keys in RFC 7748, RFC 8032, and
> possibly other algorithms. ByteArrayKeySpec can be viewed as a
> generalization of SecretKeySpec, and it will be used in a similar
> manner. The existing classes X509EncodedKeySpec and PKCS8EncodedKeySpec
> can also be used for RFC 7748 public and private key specs, respectively.
> 4) There will be no interfaces in java.security.interfaces specific to
> RFC 7748 public/private keys. A new interface called ByteArrayKey will
> be added to java.security.interfaces. This interface will expose an
> AlgorithmParameterSpec and a byte array containing the raw key value.
> Implementations of keys in RFC 7748, 8032 (and possibly other
> algorithms) can implement this interface to allow other providers to
> access the required information about the keys. Implementations can also
> achieve interoperability by using encoded representations of keys.
>
> 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. They will also both
> implement ByteArrayKey.
> 2) The KeyFactory for RFC 7748 will support translation from opaque keys
> and ByteArrayKey to X509EncodedKeySpec/PKCS8EncodedKeySpec and
> ByteArrayKeySpec (and vice-versa).
>
> 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");
> byte[] rawKeyBytes = ...
> ByteArrayKeySpec pubSpec = new ByteArrayKeySpec(
> "XDH",
> new NamedParameterSpec("X25519"),
> rawKeyBytes);
> PublicKey pubKey = kf.generatePublic(pubSpec);
>
> KeyAgreement ka = KeyAgreement.getInstance("XDH");
> ka.init(kp.getPrivate());
> ka.doPhase(pubKey, true);
> byte[] secret = ka.generateSecret();
>
> Additional notes:
> 1) The ability to specify curve domain parameters over the API is a
> useful feature, and this design accommodates the addition of this
> feature in the future. Both ByteArrayKeySpec and ByteArrayKey hold an
> AlgorithmParameterSpec rather than a more concrete type. In addition to
> using NamedParameterSpec, the parameters could be specified using some
> other type that holds domain parameters.
>
> 2) Applications that need to choose their behavior based on the type of
> (for example) public key can do so for RFC 7748 keys by calling
> Key::getAlgorithm() to determine the algorithm and then using
> ByteArrayKey to extract the required information.
>
> 3) This design supports Xuelei's general EC proposal[1]. We can use
> names like "XDHWithX25519" or perhaps simply "X25519" to specify the
> "XDH" algorithm initialized with the "X25519" NamedParameterSpec.
>
> [1]
> http://mail.openjdk.java.net/pipermail/security-dev/2017-August/016194.html
>
More information about the security-dev
mailing list