HKDFunction { public static byte[] expand(HKDFAlgorithm hkdfAlgortihm, byte[] prk, byte[] info, int outLen) throws CryptoException { try { Mac mac = Mac.getInstance(hkdfAlgortihm.getMacAlgorithm().getJavaName()); SecretKeySpec keySpec = new SecretKeySpec(prk, hkdfAlgortihm.getMacAlgorithm().getJavaName()); mac.init(keySpec); ByteArrayOutputStream stream = new ByteArrayOutputStream(); byte[] ti = new byte[0]; int i = 1; while (stream.toByteArray().length < outLen) { mac.update(ti); mac.update(info); if (Integer.toHexString(i).length() % 2 != 0) { mac.update(ArrayConverter.hexStringToByteArray("0" + Integer.toHexString(i))); } else { mac.update(ArrayConverter.hexStringToByteArray(Integer.toHexString(i))); } ti = mac.doFinal(); if (ti.length == 0) { throw new CryptoException("Could not expand HKDF. Mac Algorithm of 0 size"); } stream.write(ti); i++; } return Arrays.copyOfRange(stream.toByteArray(), 0, outLen); } catch (IOException | NoSuchAlgorithmException | InvalidKeyException | IllegalArgumentException ex) { throw new CryptoException(ex); } } private  HKDFunction(); static byte[] extract(HKDFAlgorithm hkdfAlgortihm, byte[] salt, byte[] ikm); static byte[] expand(HKDFAlgorithm hkdfAlgortihm, byte[] prk, byte[] info, int outLen); static byte[] deriveSecret(HKDFAlgorithm hkdfAlgortihm, String hashAlgorithm, byte[] prk, String labelIn,
            byte[] toHash); static byte[] expandLabel(HKDFAlgorithm hkdfAlgortihm, byte[] prk, String labelIn, byte[] hashValue,
            int outLen); static final String KEY; static final String IV; static final String FINISHED; static final String DERIVED; static final String BINDER_KEY_EXT; static final String BINDER_KEY_RES; static final String CLIENT_EARLY_TRAFFIC_SECRET; static final String EARLY_EXPORTER_MASTER_SECRET; static final String CLIENT_HANDSHAKE_TRAFFIC_SECRET; static final String SERVER_HANDSHAKE_TRAFFIC_SECRET; static final String CLIENT_APPLICATION_TRAFFIC_SECRET; static final String SERVER_APPLICATION_TRAFFIC_SECRET; static final String EXPORTER_MASTER_SECRET; static final String ESNI_IV; static final String ESNI_KEY; static final String RESUMPTION_MASTER_SECRET; static final String RESUMPTION; }
@Test public void testExpand() throws CryptoException { byte[] expand = HKDFunction .expand(HKDFAlgorithm.TLS_HKDF_SHA256, ArrayConverter .hexStringToByteArray("3b7a839c239ef2bf0b7305a0e0c4e5a8c6c69330a753b308f5e3a83aa2ef6979"), ArrayConverter.hexStringToByteArray("001009746c733133206b657900"), 16); assertArrayEquals(ArrayConverter.hexStringToByteArray("c66cb1aec519df44c91e10995511ac8b"), expand); }