/** * Creates a derived key from the given input key material (raw byte array) and an input salt * and wraps the key in a {@link SecretKeySpec} using the given output key algorithm and output * key size. * * <p>The algorithm used to derive the new key from the input key material (IKM) is the * <b>HMAC-based Extract-and-Expand Key Derivation Function (HKDF)</b> (see * <a href="http://tools.ietf.org/html/rfc5869">RFC 5869</a>) * * @param inputKeyMaterial The input key material as raw data bytes, e.g. determined from {@link SecretKey#getEncoded()} * @param inputSalt Input salt used to generate the new key (a non-secret random value!) * @param outputKeyAlgorithm Defines the algorithm of the new output key (for {@link SecretKeySpec#getAlgorithm()}) * @param outputKeySize Defines the key size of the new output key * @return Returns a new pseudorandom key derived from the input key material using HKDF * @see <a href="http://tools.ietf.org/html/rfc5869">RFC 5869</a> */ public static SaltedSecretKey createDerivedKey(byte[] inputKeyMaterial, byte[] inputSalt, String outputKeyAlgorithm, int outputKeySize) throws InvalidKeySpecException, NoSuchAlgorithmException, NoSuchProviderException { HKDFBytesGenerator hkdf = new HKDFBytesGenerator(KEY_DERIVATION_DIGEST); hkdf.init(new HKDFParameters(inputKeyMaterial, inputSalt, KEY_DERIVATION_INFO)); byte[] derivedKey = new byte[outputKeySize / 8]; hkdf.generateBytes(derivedKey, 0, derivedKey.length); return toSaltedSecretKey(derivedKey, inputSalt, outputKeyAlgorithm); }