title: Verify username and a salted password
body: <p>I have a application that usues JDBC Jquery and MYSQL that lists a table with quotes and the user can add quotes.</p>
  
  <p>i have a loggin page where i check the input of username and compare it with something that exits in the database. like this and it works fine</p>
  
  <pre><code>public Boolean findByUsername(String username) throws SQLException {
  
          ResultSet rs = null;
          Connection conn = null;
          PreparedStatement pstmt = null;
  
          try {
  
              conn = Database.getConnection();
              conn.setAutoCommit(false);
              String query = "SELECT * FROM user WHERE username = ?";
              pstmt = conn.prepareStatement(query);
              pstmt.setString(1, username);
              rs = pstmt.executeQuery();
              if (rs.next()) {
                  return true;
  
              }
          } catch (Exception e) {
              e.printStackTrace();
              throw new RuntimeException(e);
          } finally {
              conn.close();
          }
          return false;
      }
  </code></pre>
  
  <p>But when i want to compare the password i get the problem with that i salt the password with PBKDF2 it generates some random characters like this 
  1000:485b5808b4786d6aa6e5360ad157945ee927d85e49e96312:60d76b0ef1b742cfa462d84eb7fd7c37eb361717179c0a45. When i want to compare the passwordinput with something in the database i use this method.</p>
  
  <pre><code>public Boolean findByPassword(String password) throws SQLException,
              NoSuchAlgorithmException, InvalidKeySpecException {
  
          ResultSet rs = null;
          Connection conn = null;
          PreparedStatement pstmt = null;
          PasswordHash p = new PasswordHash();
          String hash = p.createHash(password);
          try {
  
              conn = Database.getConnection();
              conn.setAutoCommit(false);
              String query = "SELECT * FROM user WHERE passwd = ?";
  System.out.println("password: " +password);
  System.out.println("hashpassword " +hash);
              pstmt = conn.prepareStatement(query);
              pstmt.setString(1, hash);
              rs = pstmt.executeQuery();
              if (rs.next()) {
                  if(p.validatePassword(password, hash)){ 
                      return true;
  
                  }
  
  
              }
          } catch (Exception e) {
              e.printStackTrace();
              throw new RuntimeException(e);
          } finally {
              conn.close();
          }
          return false;
      }
  </code></pre>
  
  <p>I uses this class to hash the password</p>
  
  <pre><code>public class PasswordHash {
      public final String PBKDF2_ALGORITHM = "PBKDF2WithHmacSHA1";
  
      // The following constants may be changed without breaking existing hashes.
      public final int SALT_BYTE_SIZE = 24;
      public final int HASH_BYTE_SIZE = 24;
      public final int PBKDF2_ITERATIONS = 1000;
  
      public final int ITERATION_INDEX = 0;
      public final int SALT_INDEX = 1;
      public final int PBKDF2_INDEX = 2;
  
      /**
       * Returns a salted PBKDF2 hash of the password.
       *
       * @param password
       *            the password to hash
       * @return a salted PBKDF2 hash of the password
       */
      public String createHash(String password) throws NoSuchAlgorithmException,
              InvalidKeySpecException {
          return createHash(password.toCharArray());
      }
  
      /**
       * Returns a salted PBKDF2 hash of the password.
       *
       * @param password
       *            the password to hash
       * @return a salted PBKDF2 hash of the password
       */
      public String createHash(char[] password) throws NoSuchAlgorithmException,
              InvalidKeySpecException {
          // Generate a random salt
          SecureRandom random = new SecureRandom();
          byte[] salt = new byte[SALT_BYTE_SIZE];
          random.nextBytes(salt);
  
          // Hash the password
          byte[] hash = pbkdf2(password, salt, PBKDF2_ITERATIONS, HASH_BYTE_SIZE);
          // format iterations:salt:hash
          return PBKDF2_ITERATIONS + ":" + toHex(salt) + ":" + toHex(hash);
      }
  
      /**
       * Validates a password using a hash.
       *
       * @param password
       *            the password to check
       * @param correctHash
       *            the hash of the valid password
       * @return true if the password is correct, false if not
       */
      public boolean validatePassword(String password, String correctHash)
              throws NoSuchAlgorithmException, InvalidKeySpecException {
          return validatePassword(password.toCharArray(), correctHash);
      }
  
      /**
       * Validates a password using a hash.
       *
       * @param password
       *            the password to check
       * @param correctHash
       *            the hash of the valid password
       * @return true if the password is correct, false if not
       */
      public boolean validatePassword(char[] password, String correctHash)
              throws NoSuchAlgorithmException, InvalidKeySpecException {
          // Decode the hash into its parameters
          String[] params = correctHash.split(":");
          int iterations = Integer.parseInt(params[ITERATION_INDEX]);
          byte[] salt = fromHex(params[SALT_INDEX]);
          byte[] hash = fromHex(params[PBKDF2_INDEX]);
          // Compute the hash of the provided password, using the same salt,
          // iteration count, and hash length
          byte[] testHash = pbkdf2(password, salt, iterations, hash.length);
          // Compare the hashes in constant time. The password is correct if
          // both hashes match.
          return slowEquals(hash, testHash);
      }
  
      /**
       * Compares two byte arrays in length-constant time. This comparison method
       * is used so that password hashes cannot be extracted from an on-line
       * system using a timing attack and then attacked off-line.
       * 
       * @param a
       *            the first byte array
       * @param b
       *            the second byte array
       * @return true if both byte arrays are the same, false if not
       */
      private boolean slowEquals(byte[] a, byte[] b) {
          int diff = a.length ^ b.length;
          for (int i = 0; i &lt; a.length &amp;&amp; i &lt; b.length; i++)
              diff |= a[i] ^ b[i];
          return diff == 0;
      }
  
      /**
       * Computes the PBKDF2 hash of a password.
       *
       * @param password
       *            the password to hash.
       * @param salt
       *            the salt
       * @param iterations
       *            the iteration count (slowness factor)
       * @param bytes
       *            the length of the hash to compute in bytes
       * @return the PBDKF2 hash of the password
       */
      private byte[] pbkdf2(char[] password, byte[] salt, int iterations,
              int bytes) throws NoSuchAlgorithmException, InvalidKeySpecException {
          PBEKeySpec spec = new PBEKeySpec(password, salt, iterations, bytes * 8);
          SecretKeyFactory skf = SecretKeyFactory.getInstance(PBKDF2_ALGORITHM);
          return skf.generateSecret(spec).getEncoded();
      }
  
      /**
       * Converts a string of hexadecimal characters into a byte array.
       *
       * @param hex
       *            the hex string
       * @return the hex string decoded into a byte array
       */
      private byte[] fromHex(String hex) {
          byte[] binary = new byte[hex.length() / 2];
          for (int i = 0; i &lt; binary.length; i++) {
              binary[i] = (byte) Integer.parseInt(
                      hex.substring(2 * i, 2 * i + 2), 16);
          }
          return binary;
      }
  
      /**
       * Converts a byte array into a hexadecimal string.
       *
       * @param array
       *            the byte array to convert
       * @return a length*2 character string encoding the byte array
       */
      private String toHex(byte[] array) {
          BigInteger bi = new BigInteger(1, array);
          String hex = bi.toString(16);
          int paddingLength = (array.length * 2) - hex.length();
          if (paddingLength &gt; 0)
              return String.format("%0" + paddingLength + "d", 0) + hex;
          else
              return hex;
      }
  
      /**
       * Tests the basic functionality of the PasswordHash class
       *
       * @param args
       *            ignored
       */
  
  }
  </code></pre>
  
  <p>i call the metod here </p>
  
  <pre><code>@POST
      @Path("/login")
      @Produces(MediaType.TEXT_PLAIN)
      public String LogInUser(String username, String password)
              throws NoSuchAlgorithmException, InvalidKeySpecException,
              SQLException {
          Gson gson = new Gson();
          User theuser = gson.fromJson(username, User.class);
          if (!u.findByUsername(theuser.getUsername())
                  &amp;&amp; u.findByPassword(theuser.getPasswd())) {
              return theuser.getUsername();
          }
          return null;
  
      }
  </code></pre>
  
  <p>how do i compare the passwordinput  with something that exits in the database ?</p>