code: private byte[] pbkdf2(final String password, final byte[] salt, int iterations) {
          try {
              Mac mac = Mac.getInstance(hmacAlgorithm);
              Key key;
              if (password == null || password.isEmpty()) {
                  key = new EmptySecretKey(hmacAlgorithm);
              } else {
                  key = new SecretKeySpec(password.getBytes(), hmacAlgorithm);
              }
              mac.init(key);
              mac.update(salt);
              mac.update("\00\00\00\01".getBytes()); // Append INT(1)
  
              byte[] un = mac.doFinal();
              mac.update(un);
              byte[] uprev = mac.doFinal();
              xor(un, uprev);
  
              for (int i = 2; i < iterations; ++i) {
                  mac.update(uprev);
                  uprev = mac.doFinal();
                  xor(un, uprev);
              }
  
              return un;
          } catch (InvalidKeyException e) {
              if (password == null || password.isEmpty()) {
                  throw new UnsupportedOperationException("This JVM does not support empty HMAC keys (empty passwords). "
                      + "Please set a bucket password or upgrade your JVM.");
              } else {
                  throw new RuntimeException("Failed to generate HMAC hash for password", e);
              }
          } catch (Throwable t) {
              throw new RuntimeException(t);
          }
      }
docs: Generate the hash of the function.. Unfortunately we couldn't use
  the one provided by the Java framework because it didn't support
  others than SHA1. See https://www.ietf.org/rfc/rfc5802.txt (page 6)
  for how it is generated.
  
  @param password   The password to use
  @param salt       The salt used to salt the hash function
  @param iterations The number of iterations to sue
  @return The pbkdf2 version of the password