HKDFunction { public static byte[] extract(HKDFAlgorithm hkdfAlgortihm, byte[] salt, byte[] ikm) throws CryptoException { try { Mac mac = Mac.getInstance(hkdfAlgortihm.getMacAlgorithm().getJavaName()); if (salt == null || salt.length == 0) { salt = new byte[mac.getMacLength()]; Arrays.fill(salt, (byte) 0); } SecretKeySpec keySpec = new SecretKeySpec(salt, hkdfAlgortihm.getMacAlgorithm().getJavaName()); mac.init(keySpec); mac.update(ikm); return mac.doFinal(); } catch (NoSuchAlgorithmException | InvalidKeyException 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 testExtractNoSalt() throws CryptoException { HKDFAlgorithm hkdfAlgorithm = HKDFAlgorithm.TLS_HKDF_SHA256; byte[] salt = new byte[0]; byte[] ikm = ArrayConverter .hexStringToByteArray("0000000000000000000000000000000000000000000000000000000000000000"); byte[] result = HKDFunction.extract(hkdfAlgorithm, salt, ikm); byte[] resultCorrect = ArrayConverter .hexStringToByteArray("33ad0a1c607ec03b09e6cd9893680ce210adf300aa1f2660e1b22e10f170f92a"); assertArrayEquals(result, resultCorrect); }
@Test public void testExtractWithSalt() throws CryptoException { HKDFAlgorithm hkdfAlgorithm = HKDFAlgorithm.TLS_HKDF_SHA256; byte[] salt = ArrayConverter .hexStringToByteArray("33ad0a1c607ec03b09e6cd9893680ce210adf300aa1f2660e1b22e10f170f92a"); byte[] ikm = ArrayConverter .hexStringToByteArray("c08acc73ba101d7fea86d223de32d9fc4948e145493680594b83b0a109f83649"); byte[] result = HKDFunction.extract(hkdfAlgorithm, salt, ikm); byte[] resultCorrect = ArrayConverter .hexStringToByteArray("31168cad69862a80c6f6bfd42897d0fe23c406a12e652a8d3ae4217694f49844"); assertArrayEquals(result, resultCorrect); }
@Test public void testExtractHandshake() throws CryptoException { byte[] expand = HKDFunction .extract( HKDFAlgorithm.TLS_HKDF_SHA256, ArrayConverter .hexStringToByteArray("6f2615a108c702c5678f54fc9dbab69716c076189c48250cebeac3576c3611ba"), ArrayConverter .hexStringToByteArray("8151d1464c1b55533623b9c2246a6a0e6e7e185063e14afdaff0b6e1c61a8642")); assertArrayEquals( ArrayConverter.hexStringToByteArray("5b4f965df03c682c46e6ee86c311636615a1d2bbb24345c25205953c879e8d06"), expand); }
@Test public void testExtractEarly() throws CryptoException { byte[] expand = HKDFunction .extract(HKDFAlgorithm.TLS_HKDF_SHA256, ArrayConverter.hexStringToByteArray(""), ArrayConverter .hexStringToByteArray("0000000000000000000000000000000000000000000000000000000000000000")); assertArrayEquals( ArrayConverter.hexStringToByteArray("33ad0a1c607ec03b09e6cd9893680ce210adf300aa1f2660e1b22e10f170f92a"), expand); }