Hkdf { public static byte[] computeHkdf( String macAlgorithm, final byte[] ikm, final byte[] salt, final byte[] info, int size) throws GeneralSecurityException { Mac mac = EngineFactory.MAC.getInstance(macAlgorithm); if (size > 255 * mac.getMacLength()) { throw new GeneralSecurityException("size too large"); } if (salt == null || salt.length == 0) { mac.init(new SecretKeySpec(new byte[mac.getMacLength()], macAlgorithm)); } else { mac.init(new SecretKeySpec(salt, macAlgorithm)); } byte[] prk = mac.doFinal(ikm); byte[] result = new byte[size]; int ctr = 1; int pos = 0; mac.init(new SecretKeySpec(prk, macAlgorithm)); byte[] digest = new byte[0]; while (true) { mac.update(digest); mac.update(info); mac.update((byte) ctr); digest = mac.doFinal(); if (pos + digest.length < size) { System.arraycopy(digest, 0, result, pos, digest.length); pos += digest.length; ctr++; } else { System.arraycopy(digest, 0, result, pos, size - pos); break; } } return result; }  static byte[] computeHkdf(
      String macAlgorithm, final byte[] ikm, final byte[] salt, final byte[] info, int size); static byte[] computeEciesHkdfSymmetricKey(
      final byte[] ephemeralPublicKeyBytes,
      final byte[] sharedSecret,
      String hmacAlgo,
      final byte[] hkdfSalt,
      final byte[] hkdfInfo,
      int keySizeInBytes);  }
@Test public void testNullSaltOrInfo() throws Exception { byte[] ikm = Random.randBytes(20); byte[] info = Random.randBytes(20); int size = 40; byte[] hkdfWithNullSalt = Hkdf.computeHkdf("HmacSha256", ikm, null, info, size); byte[] hkdfWithEmptySalt = Hkdf.computeHkdf("HmacSha256", ikm, new byte[0], info, size); assertArrayEquals(hkdfWithNullSalt, hkdfWithEmptySalt); byte[] salt = Random.randBytes(20); byte[] hkdfWithNullInfo = Hkdf.computeHkdf("HmacSha256", ikm, salt, null, size); byte[] hkdfWithEmptyInfo = Hkdf.computeHkdf("HmacSha256", ikm, salt, new byte[0], size); assertArrayEquals(hkdfWithNullInfo, hkdfWithEmptyInfo); }
@Test public void testInvalidCodeSize() throws Exception { try { Hkdf.computeHkdf("HmacSha256", new byte[0], new byte[0], new byte[0], 32 * 256); fail("Invalid size, should have thrown exception"); } catch (GeneralSecurityException expected) { } }