code: public static byte[] digest(char[] plainBytes, byte[] salt, String algorithm, int iteration, int length) throws InvalidPasswordCipherException {
          if (logger.isLoggable(Level.FINE)) {
              logger.fine("algorithm : " + algorithm + " iteration : " + iteration);
              logger.fine("input length: " + plainBytes.length);
              logger.fine("salt length: " + salt.length);
              logger.fine("output length: " + length);
          }
          byte[] oBytes = null;
  
          if (plainBytes != null && plainBytes.length > 0 && algorithm != null && algorithm.length() > 0 && iteration > 0) {
              long begin = 0;
              if (logger.isLoggable(Level.FINE)) {
                  begin = System.nanoTime();
              }
              try {
                  SecretKeyFactory skf = SecretKeyFactory.getInstance(algorithm);
                  PBEKeySpec ks = new PBEKeySpec(plainBytes, salt, iteration, length);
                  SecretKey s = skf.generateSecret(ks);
                  oBytes = s.getEncoded();
              } catch (Exception e) {
                  throw (InvalidPasswordCipherException) new InvalidPasswordCipherException(e.getMessage()).initCause(e);
              }
              if (logger.isLoggable(Level.FINE)) {
                  long elapsed = System.nanoTime() - begin;
                  logger.fine("Elapsed time : " + elapsed + " ns " + (elapsed / 1000000) + " ms"); //debug
              }
          }
  
          if ((logger.isLoggable(Level.FINE)) && oBytes != null) {
              logger.fine("digest length: " + oBytes.length);
              logger.fine(hexDump(oBytes));
          }
          return oBytes;
      }
docs: perform message digest and then append a salt at the end.