6

After a little bit of research and some work I finally was able to hash salt the password now there is a question which is on my mind I have used the SHA1 method and I would like to try to use the SHA512 because I was told it's better (more secure) so the following is my code its a little bit all over the place but I think its comprehensible so:

public class Safety
{
   //calling some parameters for possible later changes
   public static final String algorithm = "PBKDF2WithHmacSHA1";
   public static final int saltbytesize = 24;
   public static final int hashbytesize = 24;
   public static final int iterations = 1000;
   public static final int iIndex = 0;
   public static final int sIndex = 1;
   public static final int pbkIndex = 2;

   public static Users passwordHash(Users user) throws NoSuchAlgorithmException,
                                                       InvalidKeySpecException
   {
      SecureRandom sR = new SecureRandom();

      byte[] pws = new byte[saltbytesize];

      sR.nextBytes(pws);
      byte[] pwh = pbkdf2(user.getPassword().toCharArray(), pws, iterations, hashbytesize);

      user.setPassword(toHex(pwh));

      byte[] sas = new byte[saltbytesize];

      sR.nextBytes(sas);

      byte[] sah = pbkdf2(user.getsA().toCharArray(), sas, iterations, hashbytesize);

      user.setsA(toHex(sah));

      user.setUserhash(pws);

      user.setSahash(sas);

      return user;
   }

   public static boolean hashpassword(String username, String password, Users user)
   throws NoSuchAlgorithmException,
          InvalidKeySpecException
   {
      byte[] pws = user.getUserhash();

      byte[] pwh = pbkdf2(password.toCharArray(), pws, iterations, hashbytesize);

      String searcher = toHex(pwh) + username;

      String searched = user.getPassword() + user.getUsername();

      if (searcher.equals(searched))
      {
         return true;
      }
      return false;
   }

   private static 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(algorithm);
      return skf.generateSecret(spec).getEncoded();
   }

   private static String toHex(byte[] array)
   {
      BigInteger bi = new BigInteger(1, array);

      String hex = bi.toString(16);

      int paddingLength = (array.length * 2) - hex.length();

      if (paddingLength > 0)
         return String.format("%0" + paddingLength + "d", 0) + hex;
      else
         return hex;
   }
}

So that's my code, however, I have not been able to make that SHA512 and I have already tried public static final String algorithm = "PBKDF2WithHmacSHA512" but that doesn't seem to be the right string for the algorithm since it throws the no such algorithm exception.

I also welcome any changes that would make the code better.

as stated above! relevant few line(s) of code

public static final String algorithm = "PBKDF2WithHmacSHA512"<<<<<

Javier
  • 12,100
  • 5
  • 46
  • 57
Fahadalkadhi95
  • 65
  • 1
  • 1
  • 6
  • 1
    always format your code to look pretty if you're asking people to look at it. Clarity of code is half the question. – Mike 'Pomax' Kamermans Dec 27 '13 at 21:09
  • Thank you and I know that but the way I hack kind off limits my ability to make it look pretty. – Fahadalkadhi95 Dec 27 '13 at 21:16
  • 1
    not really. the code you pasted has misaligned spacing and condensed statements, etc. at the very least fix that to be nice to potential question-answerers =) – Mike 'Pomax' Kamermans Dec 27 '13 at 21:48
  • Fixed it. The main problem with your code formatting appears to have been tabs - there should **never** be tabs in code, and the editing display and the output may use different tab stops, so the indentation may look different. Also, if you use a decent IDE (say NetBeans), it's actually rather difficult to write code without it having decent formatting. – Bernhard Barker Dec 27 '13 at 22:35
  • TY @Dukeling you are my hero :) – Fahadalkadhi95 Dec 27 '13 at 22:38
  • Can you trim down your example to just a few relevant lines of code? – BillRobertson42 Dec 27 '13 at 22:55

1 Answers1

6

That is not possible out of the box

The OpenJDK implementation does only provide a PBKDF2HmacSHA1Factory.java which has the "HmacSHA1" digest harcoded. As far as I tested, the Oracle JDK is not different in that sense.

What you have to do is derive the PBKDF2HmacSHA1Factory (come on, it is open!) and add a parameter to its constructor. You may avoid the mess of creating your own Provider, and just initialize and use your factory as follows:

PBKDF_SecretKeyFactory kf = new PBKDF_SecretKeyFactory("HmacSHA512");
KeySpec ks = new PBEKeySpec(password,salt,iterations,bitlen);
byte key[] = kf.engineGenerateSecret(ks).getEncoded();
Javier
  • 12,100
  • 5
  • 46
  • 57
  • Do i need to save the key[] i mean in a database? – Fahadalkadhi95 Dec 27 '13 at 23:36
  • Yes. Despite the name, the resulting "key" is actually the output of the PBKDF. An attacker cannot (but by brute force) derive the original password from the "key". – Javier Dec 27 '13 at 23:48
  • one more thing i should have asked before hand when someone logs in what i do is retrieve the key and salt and hash it again?more properly what is the use of the key? or is it actually the hashed password and i am too thick to understand? – Fahadalkadhi95 Dec 27 '13 at 23:53
  • The "key" is the hashed password. When someone logs in, you hash the provided password again (with the same salt, algorithm and number of iterations) and test if the hashes match. Te advantage is that the password is never stored in your database. – Javier Dec 28 '13 at 00:25
  • i tried it and it says PBKDF_SecretKeyFactory cannot be resolved as a type? – Fahadalkadhi95 Dec 28 '13 at 15:53
  • That class doesn't exists. You will have to write it. See te source for `PBKDF2HmacSHA1Factory` linked above. – Javier Dec 29 '13 at 01:37
  • um i understood that but excuse my ....."knowledgementness".... how ever how do i write it exactly the link you gave me is to a class named ´PBKDF2HmacSHA1Factory´ ? – Fahadalkadhi95 Dec 29 '13 at 01:55
  • 1
    I think the changes are trivial: you need a factory for PBKDF with "HmacSHA512", class `PBKDF2HmacSHA1Factory` is a factory for PBKDF with "HmacSHA1": **copy the source, rename it, replace "HmacSHA1" by "HmacSHA512", and have a happy new year**. – Javier Dec 29 '13 at 06:44
  • Happy new year to you too and may your next year be what you want it to be i will try it and give you feed back hopefully it works and I start working on my next step :) – Fahadalkadhi95 Dec 29 '13 at 12:28
  • i think i also need to update my JDK because there is a class that isnt installed in that class ill try installing these classes and experiment a little – Fahadalkadhi95 Dec 29 '13 at 14:22
  • 5
    Java 8 now has PBKDF2HmacSHA512 available - https://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html – Anti-weakpasswords Feb 08 '16 at 05:47