Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8189808

Key Derivation API

    XMLWordPrintable

Details

    • JEP
    • Status: Draft
    • P3
    • Resolution: Unresolved
    • None
    • security-libs
    • None
    • Jamil Nimeh
    • Feature
    • Open
    • JDK
    • M
    • M

    Description

      Summary

      Create new APIs for deriving cryptographic keys.

      Goals

      • Provide a straightforward interface that lets consumers specify KDF algorithms by name
      • Provide an API that allows 3rd party developers to make their own KDF implementations using this framework

      Non-Goals

      • This JEP will not cover any specific SunJCE implementations (e.g. TLS-PRF, HKDF, PBKDF2, etc.)
      • Migration of existing KDF algorithms from other JCE APIs like KeyGenerator to this new KDF API.

      Success Metrics

      Most measurable criteria for the KDF feature would reside in individual implementations of key derivation functions and are outside the scope of this JEP.

      Motivation

      Currently in the JCE we have APIs that cover key generation and key agreement as methods for obtaining secret keys, but we do not have an API for key derivation. What we have done today is take key derivation algorithms such as TLS-PRF or PBKDF2 and made them fit into a KeyGenerator. Long term however, it may make more sense to provide a KeyDerivation family of APIs and implementations which would provide interfaces better suited to these kinds of cryptographic operations.

      This API will also let us publicly expose KDF algorithms that have been kept private up to now, such as TLS-PRF. It gives us a derivation framework to implement the key schedule for TLS 1.3, as well as the master-secret and key-and-mac calculations that are done in TLS 1.2 and earlier. The new TLS framework will be one of the first consumers of this API.

      Description

      The API itself will not modify any existing classes. It will follow a similar form to many of the other cryptographic APIs that are used in the JDK now (e.g. KeyAgreement, KeyGenerator). New classes would include a primary consumer-level class (javax.crypto.KeyDerivation), an underlying Service Provider Interface (javax.crypto.KeyDerivationSpi), and a key-specific derivation parameter class (java.security.spec.DerivedKeyParameterSpec). Other classes may be created as this API evolves. While outside the scope of the Key Derivation API, individual KDF implementations may also create new AlgorithmParameterSpec classes.

      The KeyDerivation class would provide the instantiation methods (getInstance) which would also initialize a KDF. It will also provide methods for the derivation of key material (deriveKey, deriveKeys), along with methods to get the algorithm (getAlgorithm) and Provider (getProvider), similar to other cryptographic APIs in JDK. The KeyDerivationSpi will have methods for initialization (engineInit) and derivation (deriveKeys). Finally, the DerivedKeyParameterSpec will have common parameters that would be specified for keys (algorithm name/label, key length), along with accessor methods to return those values.

      Use of KDF API

      Use of the KDF API follows a similar pattern of calls like most JCE APIs. A KeyDerivation object is instantiated via one of the getInstance() calls, followed by an initialization where the input key and parameters (if needed by the KDF algorithm) is applied. From that point on, keys can be derived singly or in batch form. A sample single-key derivation using HKDF to output a single AES key would look like this:

      byte[] salt;
      byte[] info; SecretKey inputKey; // Populate salt and info arrays and obtain SecretKey object // (external to this code snippet; not shown) ... ... // Get a KeyDerivation object try { AlgorithmParameterSpec hkdfSpec = new HkdfParameterSpec(inputKey, salt, info); KeyDerivation kdf = KeyDerivation.getInstance("HkdfSHA256", hkdfSpec); // Next specify type and length of the desired key and place into parameter spec DerivedKeyParameterSpec keySpec = new DerivedKeyParameterSpec("AES", 32); // Derive the key SecretKey derivedAesKey = kdf.deriveKey(keySpec); } catch (GeneralSecurityException ge) { System.out.println("Ouch! Caught " + ge); } catch (InvalidKeyException ke) { System.out.println("Invalid Key: " + ke); }

      Alternatives

      One alternative to a new KDF API would be to continue to force KDF algorithms to fit into existing APIs such as KeyGenerator (as TLS-PRF does today) or SecretKeyFactory (PBKDF2).

      Testing

      Testing will need to be done both with the API itself (JCK testing) to make sure that positive and negative conditions are accurately reflected by the documented behavior. This will most likely require at least one actual implementation in the SunJCE provider (HKDF, TLS-PRF, etc.). Tests should include known-answer vectors to ensure correctness. These need not be exhaustive tests, since exhaustive known answer tests fall within the testing requirements of the KDF implementation. These KAT tests would be done to ensure that processing at the KeyDerivation and KeyDerivationSpi do not corrupt or alter the data, and that multi-key derivations preserve the order that they are requested in.

      Risks and Assumptions

      One inherent assumption/risk, as discussed above, is that fully testing the API will require at least one implementation. There are implementations that are in prototype states but are working in terms of generating correct output, so that mitigates the risk somewhat. Also this API will be subject to community review and may evolve during that review process.

      Attachments

        Issue Links

          Activity

            People

              kdriver Kevin Driver
              jnimeh Jamil Nimeh
              Jamil Nimeh Jamil Nimeh
              Votes:
              0 Vote for this issue
              Watchers:
              7 Start watching this issue

              Dates

                Created:
                Updated: