RFR: Proposed HKDF API (JDK-8145255)

Michael StJohns mstjohns at comcast.net
Wed Apr 20 18:27:51 UTC 2016


On 4/20/2016 1:40 PM, Jamil Nimeh wrote:
>
>
> On 04/15/2016 05:02 PM, Michael StJohns wrote:
>> On 4/15/2016 5:33 PM, Jamil Nimeh wrote:
>>> Hi Mike, thanks for your comments and suggestions, I need to digest 
>>> some of this but I have some follow-up questions to start:
>>>
>>> On 04/15/2016 12:54 PM, Michael StJohns wrote:
>>>> Hi Jamil -
>>>>
>>>> I need to look at this a bit more, but I think its probably 
>>>> incorrect.  Basically, KDFs should be able to provide multiple keys 
>>>> from a single call, not a single key as you've described here.
>>> Would that mean that a second call to Kdf.generateKey() with no 
>>> prior reinitialization would create a new key of whatever output 
>>> length it was initialized with, assuming the end state from the 
>>> previous call?  In other words, the output from generateKey1 and 
>>> generateKey2 would yield the same bytes as it would if a single call 
>>> was made for the combined length and then segmented after the fact?
>>
>> No.  Calling generateKey again would get you the exact same key as 
>> before.  Same initial key, same input data, same output data.  I'd 
>> probably wipe the state and require a reinitialization rather than do 
>> that.  You *don't* want to treat this like a DRBG.
> Ah, I understand what you mean now.  The current implementation will 
> not generate a different key if you call generateKey twice. As you 
> said, same inputs yield the same result.
>>
>>
>>>> They may also may need to provide non-key cryptographic material 
>>>> such as IV's.  The TLS1.2 KDF (PRF) is an example of this.
>>>>
>>>> There's this other problem that you're outputting unwrapped data - 
>>>> which means you can never define this to run as a hardware module 
>>>> as the outputs are byte arrays.
>>> The output from SunJCE's implementation (the only one we're doing 
>>> right off the bat) would start as a byte array internally from 
>>> HKDFKeyGenerator, true.  But SunJCE's implementation is supposed to 
>>> be native and not assuming outside hardware, AFAIK. If we had to 
>>> interact with an HSM, I would think we'd need to define an 
>>> HKDFKeyGenerator class within the SunPKCS11 provider, or some other 
>>> provider capable of speaking to said HSM.
>>
>> Probably, but for software keys you can usually use the "getBytes()" 
>> or equivalent (getEncoded() for SecretKeySpec...) to get out the 
>> bytes if you really need them.   Its harder to do this the other way 
>> - if you always have to output bytes, then it won't work in most HSMs.
> I'm not sure how HSMs are coming into play here, other than that they 
> could possibly be the provider of the HMAC algorithm. SunJCE's 
> implementation is going to build the key as it does successive HMAC 
> operations.  Even from an HSM, while the key for doing the HMAC might 
> live in the HSM prior to starting HKDF, the output is going to be a 
> byte array because it's HMAC.  Until HSMs have their own way of 
> providing HKDF that yields an object handle (to put it in PKCS#11 
> parlance) I don't see what we could do in this particular provider 
> differently.  Because we have to build the key as a byte array, we're 
> already exposed in host memory.

A software-based provider of a KDF will produce a byte array and wrap it 
in a software Key implementation.  The byte array will be extractable.  
A hardware-based provider of a KDF will produce a handle to an internal 
key and wrap the handle in a hardware Key implementation.  The key 
stream that makes up the key may or may not be extractable for a 
hardware implementation, but is probably always extractable for a 
software one.

Don't focus on the HMAC function - focus on the KDF function that uses 
the HMAC (or hash or CMAC) function as its RBG engine.   The output of 
an HMAC function (or cmac or hash for that matter) is public data.  The 
output of the KDF is mostly non-public key material.  The fact that a 
given KDF uses a public output function as its engine function doesn't 
mean that the output of the KDF is always public data.

Its somewhat a problem that the same key can be used to key both an HMAC 
and a KDF based on HMAC, but that's a bug, not a feature.

The way you deal with this is bifurcate the key space or to tag the key 
material with its use.  E.g. add a javax.crypto.kdf.MasterKey interface 
and use that to type what gets fed to the KDF.  Even though it has the 
same general characteristics as a SecretKey, it can't be a sub interface 
to SecretKey so you can enforce the separation.

>
> If such mechanisms come along from PKCS#11 providers,

The TLS 1.2/1.1 Mechanism already exists.  But it's very clumsy and 
basically wrong.

>>
>>
>>>
>>> My PKCS#11 is a bit rusty, but if the underlying provider had its 
>>> own HDKF mechanism then I would guess we could call into C_DeriveKey 
>>> using that mech and the template could mark the resulting key as 
>>> sensitive or sensitive/non-extractable.  If it didn't have an HKDF 
>>> mechanism (OASIS hasn't defined an HKDF mechanism yet, have they?) 
>>> then we could implement HKDF in terms of HMAC calls, but that 
>>> doesn't solve the concern you have, since IIRC C_Sign calls would be 
>>> used and those return byte arrays which would expose the key as 
>>> bytes until a C_CreateObject could be called.
>>
>> If the Master Key or Key Derivation Key is inside the HSM, then you 
>> have to use whatever mechanism that gets described to do the KDF 
>> function.  AFAICT, Oasis hasn't yet done a KDF for HKDF. You might 
>> ask Valerie Fenwick @oracle to put it on the list of things to do (or 
>> you could even write a contribution :-) ).
> I'll leave HKDF at Solaris PKCS#11 to the Solaris PKCS#11 folks. But 
> taking advantage of that feature once present wouldn't happen within a 
> SunJCE provider.  It would require new code in the PKCS#11 provider I 
> would think.  This first swing at HKDF doesn't tackle that.  Even if 
> we did, at this point it would be nothing more than a bunch of HMAC 
> calls, which takes us right back to getting byte array output from the 
> PKCS#11 target library/implementation/hardware.

I don't think you can do this with the current API and do what you want 
to do.  I think you really do need a KDF API.

In PKCS11 you get handles to the session keys if you call C_DeriveKey to 
derive TLS key material.  The handles to the session key end up in the 
structure you pass to the call so the keys never actually come out as 
bytes.  I would expect that to be true with the TLS1.3 HKDF function as 
well - or pretty close.

If they actually come out as keys from a KDF, then you can't actually 
extract the key bytes from the keys if you do it correctly.

If they come out as bytes into software land, then you have to put them 
back into the HSM and you lose the secrecy of the key material in the in 
and out process.


>>
>>>
>>> Assuming though that SunPKCS11 could talk to an HSM that had an HKDF 
>>> mech in their PKCS#11 library, and we added HKDF support to that 
>>> provider, the output from KeyGenerator.generateKey() is a SecretKey, 
>>> one that would I believe be a wrapper around an object handle rather 
>>> than holding the actual key bytes (I'd have to go look to be sure). 
>>> I think that's why calls like Key.getEncoded() are not guaranteed to 
>>> return encoded data...in some cases like a PKCS#11 sensitive key we 
>>> wouldn't be allowed access to it.
>>
>> Exactly.
>>
>>>>
>>>> So I'd generalize this more as: (This is a single pass design - I 
>>>> haven't gone back and tweaked the obvious mistakes - not enough 
>>>> time right now).
>>> Are you suggesting that your KDF solution below is accessed through 
>>> the KeyGenerator API and the implementation would derive from 
>>> KeyGeneratorSpi?  I ask because two of the forms of init you provide 
>>> below are not part of the API.
>>
>> I think a KDF is a different beast than a KeyGenerator.  Trying to 
>> overload KeyGenerator to work with KDF's is problematic. 
>> KeyGenerators generate exactly one type of key. 
>> KeyDerivationFunctions can generate ANY type of key.
> From talking with one of the other JSL guys here, they say that 
> KeyGenerator is the vehicle usually employed for this kind of thing.  
> I went back and forth with Xuelei on your point a bit over the last 
> couple days.  As I understand the API and its requirements, it seems 
> like a different kind of key (say, a TLS 1.x key and mac block) 
> requires a different algorithm provided to the 
> KeyGenerator.getInstance() call, along with possibly a different 
> AlgorithmParameterSpec (if you go that route to init). Some of the TLS 
> key generators used for PRF are an example of this (also in 
> com.sun.crypto.provider).  They return SecretKey objects that are 
> actually built from multiple SecretKey objects inside (client 
> read/write keys, HMAC keys, etc.)

Yup... and it would be really nice to fix that and generalize that. 
KeyGeneration is *really* a different beast from KeyDerivation and the 
more I spend time on it, the more I realize how badly we've done on the 
design.  (The TLS trick I mentioned about IVs?  It can be repeated with 
IPSEC too....).

>>
>>
>>>
>>> Or are you thinking of it as standalone or derived from another 
>>> API?  Some of the calls make it look like it's intended to be a 
>>> KeyGenerator and that's why I ask.
>>>>
>>>> Kdf.getInstance(String algName);
>>>>
>>>> Kdf.init (AlgorithmParameterSpec kdfSpec);  // only one key 
>>>> produced, well defined by the algName, no parameters required.
>>>> Kdf.init (AlgorithmParameterSpec kdfSpec, KDFAlgorithmParameterSpec 
>>>> keyspec);
>>>> Kdf.init (AlgorithmParameterSpec kdfSpec, 
>>>> KDFAlgorithmParameterSpec[] keyspecs);
>>>>
>>>> Key xxx = Kdf.generateKey();
>>>> Key[] xxx = Kdf.generateKeys();
>>> Why do we need an array form for generateKeys?  Is that just a 
>>> convenience?  Is it inspired by the TLS-style key/mac/IV derivation?
>>
>> This goes back to the fact that you call generate only once per 
>> init.   You want to make sure that if the order of the keys to which 
>> key material is assigned changes, then so to does the underlying 
>> derived key stream.
>>
>>  (I've got a long rant related to this - but basically, you want to 
>> make it possible (or least have the API make it possible) to mixin 
>> all of the assignment of key material to cryptographic objecs - e.g. 
>> key type, key length, key protection bits etc. HDKF might not do 
>> this, but other KDFs will and do.  The makes it possible for an HSM 
>> to use the mixin data to figure out what protection to assign to the 
>> generated keys in a way that depends on the derivation constants - 
>> any change to the constants changes the entire key stream).    It 
>> turns out that its trivial to extract TLS keys from an HSM because 
>> the TLS KDF doesn't mixin the key type and lengths for the keys and 
>> IV it generates, so the derived key stream doesn't change if you 
>> change the keys to be produced.  See 
>> https://www.ietf.org/mail-archive/web/i-d-announce/current/msg67039.html 
>> - I need to go back and get this accepted.
> Is that the stuff also talked about in OASIS where the TLS key and mac 
> derivation template could be changed to setting zero-length data and 
> hmac keys and size the IV output to the required keystream?  I thought 
> that was pretty clever.

Yup.  Since the assignment information (key type and length and other 
things) isn't a mixin to the key stream generation, simply changing the 
lengths of the individual element output lengths allows you to assign 
exactly the same key stream to any mix of public and non-public output 
elements.

Mike


>>
>>
>>
>>>>
>>>> public interface KDFAlgorithmParameterSpec extends 
>>>> AlgorithmParameterSpec {
>>>>     public KDFParameters[] getParams();
>>>> }
>>>>
>>>> public class SecretKeyAlgorithmSpec implements 
>>>> KDFAlgorithmParameterSpec  {
>>>>     public SecretKeyAlgorithmSpec (String algorithm, int size, 
>>>> KDFParameters ... params );
>>>>     public int getSize();
>>>>     public String getAlgorithm();
>>>>     public KDFParameters[] getParams();
>>>> }
>>>>
>>>> public interface KDFParameters{};
>>>>
>>>> KDFParameters is a marker interface to deal with mixin parameters 
>>>> that are specific to the key material.
>>>>
>>>> I'd define HKDF as the instance type for the Kdf.getInstance().
>>>>
>>>> I'd define HKDFAlgorithmParameterSpec  and place the info on which 
>>>> PRF function to use in that spec along with any other instance 
>>>> specific stuff.  This is also where you put the context and label 
>>>> mixin data.
>>>>
>>>>
>>>> I'd then define the "HKDFExtract" and "HKDFExpand" as two separate 
>>>> KDFs.  The first produces a single Key of instance type MasterKey 
>>>> (which is a sub type of SecretKey) which is a well known length 
>>>> based on the provided PRF.  The second produces whatever you ask 
>>>> for based on the key spec's you provide.
>>>>
>>>> This generalizes well to other KDFs including SP800-108.
>>> I'll have to spend a little time digesting what you put down here. 
>>> Interesting stuff.
>>
>> Yeah - I think this is probably more than you want to do, and is 
>> going to require an API change, but I also think that is the right 
>> way to do it.
>>
>> Mike
>>
>>>
>>> --Jamil
>>>>
>>>> Mike
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> On 4/15/2016 2:06 PM, Jamil Nimeh wrote:
>>>>> Hello all,
>>>>>
>>>>> We are looking to add HKDF support as a KeyGenerator into OpenJDK 
>>>>> 9.  This will be available for general-purpose use. I've 
>>>>> documented the proposed API below.
>>>>>
>>>>> RFE: https://bugs.openjdk.java.net/browse/JDK-8145255
>>>>> Proof-of-concept implementation: 
>>>>> http://cr.openjdk.java.net/~jnimeh/reviews/8145255/webrev.1/
>>>>>
>>>>> A set of new standard algorithm names would be created that define 
>>>>> the HMAC algorithm used with HKDF: HkdfSHA224, HkdfSHA256, 
>>>>> HkdfSHA384 and HkdfSHA512.  We can at a later date include HKDF 
>>>>> variants that use other supported HMAC algorithms.
>>>>>
>>>>> Instantiation:
>>>>> --------------
>>>>> In order to do HKDF derivations, a KeyGenerator of the appropriate 
>>>>> type must be obtained.  This is done using one of the 
>>>>> KeyGenerator.getInstance methods, specifying the underlying HMAC 
>>>>> type using one of the names listed above.
>>>>>
>>>>> Initialization:
>>>>> ---------------
>>>>> The resulting HKDF KeyGenerator, in order to be compliant with the 
>>>>> KeyGenerator API, may be used to generate a key without any 
>>>>> further initialization.  In this case, the Extract-then-Expand 
>>>>> operation will be performed using null salt and 
>>>>> application-specific information, and a random input key.  The 
>>>>> resulting output key will be sized to the output length of the 
>>>>> underlying HMAC.  This can be used as a way to obtain a random key.
>>>>>
>>>>> The HKDF KeyGenerator supports all five flavors of the init 
>>>>> method.  The resulting behavior differs between each flavor however.
>>>>>
>>>>> KeyGenerator.init(SecureRandom):
>>>>> --------------------------------
>>>>> If this version of the init method is used, the KeyGenerator will 
>>>>> behave similarly to the default initialization, with the exception 
>>>>> that the caller may provide their own SecureRandom source for the 
>>>>> input key. A null value is allowed, in which case the 
>>>>> implementation will obtain the default SecureRandom implementation 
>>>>> for generating the input key.
>>>>>
>>>>> KeyGenerator.init(int);
>>>>> KeyGenerator.init(int, SecureRandom);
>>>>> -------------------------------------
>>>>> These two versions of the KeyGenerator allow the caller to provide 
>>>>> the resulting key length and, in the second case provide a 
>>>>> SecureRandom source.  The caller must provide a non-negative 
>>>>> length value in bytes.  A value of zero is allowed and returns a 
>>>>> key of the same length as the underlying HMAC.  In both forms the 
>>>>> Extract-then-Expand operation will be performed with null salt and 
>>>>> application-specific information, and a random input key. If a 
>>>>> SecureRandom value is provided, its behavior is similar to 
>>>>> KeyGenerator.init(SecureRandom).
>>>>>
>>>>> KeyGenerator.init(AlgorithmParameterSpec);
>>>>> KeyGenerator.init(AlgorithmParameterSpec, SecureRandom);
>>>>> --------------------------------------------------------
>>>>> These versions of the init method allow the caller to customize 
>>>>> the input parameters to the HKDF generator as well as select the 
>>>>> HKDF function to perform.
>>>>>
>>>>> Users desiring a specific HKDF function would initialize it using 
>>>>> one of three new AlgorithmParameterSpec classes: 
>>>>> HkdfExtractParameterSpec, HkdfExpandParameterSpec, or 
>>>>> HkdfParameterSpec.  These three parameter spec classes are used to 
>>>>> initialize the HKDF key generator to perform the HKDF-Expand, 
>>>>> HKDF-Extract or a combination HKDF-Extract-then-Expand operation, 
>>>>> respectively.
>>>>>
>>>>> The init(AlgorithmParameterSpec, SecureRandom) ignores the 
>>>>> SecureRandom parameter, and requires that input key material (IKM) 
>>>>> or a pseudorandom key (PRK) is provided.
>>>>>
>>>>> Key Generation:
>>>>> ---------------
>>>>> Once initialized (default or via one of the init methods) a key is 
>>>>> generated by calling KeyGenerator.generateKey().
>>>>>
>>>>>
>>>>> The Specification:
>>>>> ------------------
>>>>> Three new AlgorithmParameterSpec classes will be created to 
>>>>> initialize HKDF KeyGenerator objects:
>>>>> HkdfParameterSpec: For performing the Extract-then-Expand operation
>>>>> HkdfExtractParameterSpec: For performingthe HKDF-Extract operation
>>>>> HkdfExpandParameterSpec: For performing the HKDF-Expand operation
>>>>>
>>>>>
>>>>> /**
>>>>>  * Parameters for the Extract operation of the HMAC-based 
>>>>> Extract-and-Expand
>>>>>  * Key Derivation Function (HKDF). The HKDF function is defined in
>>>>>  * <a href="http://tools.ietf.org/html/rfc5869">RFC 5869</a>.
>>>>>  * This class is used to initialize KeyGenerators in the HKDF 
>>>>> family of
>>>>>  * generators, specifically for the HKDF Extract function.
>>>>>  * <p>
>>>>>  * Here is an example of how an HkdfExtractParameterSpec would be 
>>>>> used to
>>>>>  * initialize an HKDF KeyGenerator:
>>>>>  * <pre>
>>>>>  *     byte[] salt;
>>>>>  *     SecretKey inputKey;
>>>>>  *     SecretKey resultingPRK;
>>>>>  *
>>>>>  *     // salt and inputKey values populated with data
>>>>>  *     ...
>>>>>  *
>>>>>  *     // Get an instance of the HKDF KeyGenerator
>>>>>  *     hkdfGen = KeyGenerator.getInstance("HkdfSHA256");
>>>>>  *
>>>>>  *     // Create the spec object and use it to initialize the 
>>>>> generator.
>>>>>  *     hkdfGen.init(new HkdfExtractParameterSpec(salt, inputKey));
>>>>>  *
>>>>>  *     // Generate the PRK
>>>>>  *     resultingPRK = hkdfGen.generateKey();
>>>>>  * </pre>
>>>>>  *
>>>>>  * @since 9
>>>>>  */
>>>>> public final class HkdfExtractParameterSpec implements 
>>>>> AlgorithmParameterSpec {
>>>>>
>>>>>     /**
>>>>>      * Constructs a new HkdfExtractParameterSpec with the given 
>>>>> salt value
>>>>>      * and key material
>>>>>      *
>>>>>      * @param salt the salt value, or {@code null} if not 
>>>>> specified.  The
>>>>>      *      contents of the array are copied to protect against 
>>>>> subsequent
>>>>>      *      modification.
>>>>>      * @param inputKey the Input Keying Material (IKM).
>>>>>      *
>>>>>      * @throws NullPointerException if {@code inputKey} is {@code 
>>>>> null}.
>>>>>      */
>>>>>     public HkdfExtractParameterSpec(byte[] salt, SecretKey inputKey);
>>>>>
>>>>>     /**
>>>>>      * Returns the Input Keying Material (IKM).
>>>>>      *
>>>>>      * @return the Input Keying Material.
>>>>>      */
>>>>>     public SecretKey getIKM();
>>>>>
>>>>>     /**
>>>>>      * Returns the salt value.
>>>>>      *
>>>>>      * @return a copy of the salt value or {@code null} if no salt 
>>>>> was provided.
>>>>>      */
>>>>>     public byte[] getSalt();
>>>>> }
>>>>>
>>>>> HkdfExpandParameterSpec:
>>>>> ------------------------
>>>>> /**
>>>>>  * Parameters for the Expand operation of the HMAC-based 
>>>>> Extract-and-Expand
>>>>>  * Key Derivation Function (HKDF). The HKDF function is defined in
>>>>>  * <a href="http://tools.ietf.org/html/rfc5869">RFC 5869</a>.
>>>>>  * <p>
>>>>>  * Here is an example of how an HkdfExpandParameterSpec would be 
>>>>> used to
>>>>>  * initialize an HKDF KeyGenerator:
>>>>>  * <pre>
>>>>>  *     byte[] info;
>>>>>  *     SecretKey pseudoRandomKey;
>>>>>  *     SecretKey resultingKey;
>>>>>  *
>>>>>  *     // pseudoRandomKey and context info values populated with data
>>>>>  *     ...
>>>>>  *
>>>>>  *     // Get an instance of the HKDF KeyGenerator
>>>>>  *     hkdfGen = KeyGenerator.getInstance("HkdfSHA256");
>>>>>  *
>>>>>  *     // Create the spec object and use it to initialize the 
>>>>> generator.
>>>>>  *     // Ask for a 64-byte key to be output.
>>>>>  *     hkdfGen.init(new HkdfExpandParameterSpec(pseudoRandomKey, 
>>>>> info, 64));
>>>>>  *
>>>>>  *     // Generate the key
>>>>>  *     resultingKey = hkdfGen.generateKey();
>>>>>  * </pre>
>>>>>  *
>>>>>  * @since 9
>>>>>  */
>>>>> public final class HkdfExpandParameterSpec implements 
>>>>> AlgorithmParameterSpec {
>>>>>
>>>>>     /**
>>>>>      * Constructs a new HkdfExpandParameterSpec.
>>>>>      *
>>>>>      * @param prk the pseudorandom key used for HKDF-Expand.
>>>>>      * @param info optional context and application specific 
>>>>> information or
>>>>>      *      {@code null} if no info data is provided.  The 
>>>>> contents of the
>>>>>      *      array are copied to protect against subsequent 
>>>>> modification.
>>>>>      * @param outLen the length in bytes of the output data
>>>>>      *
>>>>>      * @throws NullPointerException if {@code prk} is {@code null}.
>>>>>      * @throws IllegalArgumentException if {@code outLen} is a
>>>>>      *      non-positive value.
>>>>>      */
>>>>>     public HkdfExpandParameterSpec(SecretKey prk, byte[] info, int 
>>>>> outLen);
>>>>>
>>>>>     /**
>>>>>      * Returns a {@link SecretKey} object containing the 
>>>>> pseudorandom key (PRK).
>>>>>      *
>>>>>      * @return a {@link SecretKey} object containing the 
>>>>> pseudorandom key.
>>>>>      */
>>>>>     public SecretKey getPRK();
>>>>>
>>>>>     /**
>>>>>      * Returns a copy of the context and application specific 
>>>>> information.
>>>>>      *
>>>>>      * @return a copy of the context and application specific 
>>>>> information.
>>>>>      *      This may be {@code null} or empty if no specific 
>>>>> information was
>>>>>      *      provided.
>>>>>      */
>>>>>     public byte[] getInfo();
>>>>>
>>>>>     /**
>>>>>      * Returns the length in bytes of the output key to be produced.
>>>>>      *
>>>>>      * @return the length in bytes of the output key to be produced.
>>>>>      */
>>>>>     public int getOutputLength();
>>>>> }
>>>>>
>>>>>
>>>>> HkdfParameterSpec:
>>>>> ------------------
>>>>>
>>>>> /**
>>>>>  * Parameters for the combined Extract-then-Expand operation of 
>>>>> the HMAC-based
>>>>>  * Extract-and-Expand Key Derivation Function (HKDF). The HKDF 
>>>>> function
>>>>>  * is defined in <a href="http://tools.ietf.org/html/rfc5869">RFC 
>>>>> 5869</a>.
>>>>>  * <p>
>>>>>  * Here is an example of how an HkdfParameterSpec would be used to 
>>>>> initialize
>>>>>  * an HKDF KeyGenerator:
>>>>>  * <pre>
>>>>>  *     byte[] salt;
>>>>>  *     byte[] info;
>>>>>  *     SecretKey inputKey;
>>>>>  *     SecretKey resultingKey;
>>>>>  *
>>>>>  *     // salt, info and inputKey values populated with data
>>>>>  *     ...
>>>>>  *
>>>>>  *     // Get an instance of the HKDF KeyGenerator
>>>>>  *     hkdfGen = KeyGenerator.getInstance("HkdfSHA256");
>>>>>  *
>>>>>  *     // Create the spec object and use it to initialize the 
>>>>> generator.
>>>>>  *     // Ask for a 64-byte key to be output.
>>>>>  *     hkdfGen.init(new HkdfParameterSpec(inputKey, salt, info, 64));
>>>>>  *
>>>>>  *     // Generate the key
>>>>>  *     resultingKey = hkdfGen.generateKey();
>>>>>  * </pre>
>>>>>  *
>>>>>  * @since 9
>>>>>  */
>>>>> public final class HkdfParameterSpec implements 
>>>>> AlgorithmParameterSpec {
>>>>>
>>>>>     /**
>>>>>      * Constructs a new HkdfParameterSpec.
>>>>>      *
>>>>>      * @param inputKey the input keying material used for the
>>>>>      *      HKDF-Extract-then-Expand operation.
>>>>>      * @param salt the salt value, or {@code null} if not 
>>>>> specified.  The
>>>>>      *      contents of the array are copied to protect against 
>>>>> subsequent
>>>>>      *      modification.
>>>>>      * @param info optional context and application specific 
>>>>> information or
>>>>>      *      {@code null} if no info data is provided.  The 
>>>>> contents of the
>>>>>      *      array are copied to protect against subsequent 
>>>>> modification.
>>>>>      * @param outLen the length in bytes of the output data
>>>>>      *
>>>>>      * @throws NullPointerException if {@code inputKey} is {@code 
>>>>> null}.
>>>>>      * @throws IllegalArgumentException if {@code outLen} is a
>>>>>      *      non-positive value.
>>>>>      */
>>>>>     public HkdfParameterSpec(SecretKey inputKey, byte[] salt, 
>>>>> byte[] info,
>>>>>             int outLen);
>>>>>
>>>>>     /**
>>>>>      * Returns the Input Keying Material (IKM).
>>>>>      *
>>>>>      * @return the Input Keying Material.
>>>>>      */
>>>>>     public SecretKey getIKM();
>>>>>
>>>>>     /**
>>>>>      * Returns the salt value.
>>>>>      *
>>>>>      * @return a copy of the salt value or {@code null} if no salt 
>>>>> was provided.
>>>>>      */
>>>>>     public byte[] getSalt();
>>>>>
>>>>>     /**
>>>>>      * Returns a copy of the context and application specific 
>>>>> information.
>>>>>      *
>>>>>      * @return a copy of the context and application specific 
>>>>> information.
>>>>>      *      This may be {@code null} or empty if no specific 
>>>>> information was
>>>>>      *      provided.
>>>>>      */
>>>>>     public byte[] getInfo();
>>>>>
>>>>>     /**
>>>>>      * Returns the length in bytes of the output key to be produced.
>>>>>      *
>>>>>      * @return the length in bytes of the output key to be produced.
>>>>>      */
>>>>>     public int getOutputLength();
>>>>> }
>>>>
>>>
>>
>



More information about the security-dev mailing list