0

I'm trying to convert a Node.js authentication using passport-local to a Java based one

Node.js use this code:

crypto.pbkdf2Sync(password, new Buffer(this.salt, 'base64'), 10000, 64).toString('base64');

I'm trying to replicate this in java using this code:

KeySpec spec = new PBEKeySpec(password.toCharArray(), salt.getBytes(), 100000, 64 * 8);
SecretKeyFactory key = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
byte[] hashedPassword = key.generateSecret(spec).getEncoded();
hashPassword = new String(Base64.encodeBase64(hashedPassword));

But my generated key is always different than node.js one. i've also tried with different encodings in getBytes() using UTF-16LE as someone pointed here in other threads but with no luck. I'm pretty sure that pbkdf2Sync in node.js use SHA1 when no digest is used. Can anyone confirm also this?

Thank you

UPDATE

I've resolved using Java8 Base64 decoding. This is the right function to use (if someone needs it):

final char[] cPassword = password.toCharArray();
final byte[] bSalt = Base64.getDecoder().decode(utente.getSalt().getBytes());
KeySpec spec = new PBEKeySpec(cPassword, bSalt, 10000, 64 * 8);
SecretKeyFactory key = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
byte[] hashedPassword = key.generateSecret(spec).getEncoded();
String hashPassword = new String(Base64.getEncoder().encode(hashedPassword));

hashPassword will have the same Node.js password

  • Is it typo or your third argument is really different in code too? 10,000 -> 100, 000 – CuriousMind Oct 19 '16 at 10:11
  • yes. Is a typo. fixed but same result – Andrea Palmate' Oct 19 '16 at 12:38
  • Why are you setting the 4th argument as `64*8`. I guess you should set it to just `64`. – CuriousMind Oct 19 '16 at 13:01
  • no. the argument is 64 * 8 because PBEKeySpec is different than pbkdf2Sync and the parameters needs to be multiplied by 8 otherwise you will receive a key of 12 bytes (i've also found a page that explain why but i don't find it anymore..) – Andrea Palmate' Oct 19 '16 at 13:19
  • the SHA1 is the default one and so i'm sure that SecretKeyFactory is correct: https://github.com/ericelliott/credential/blob/master/credential.js This other link: http://stackoverflow.com/questions/34462316/replicating-java-password-hashing-code-in-node-js-pbkdf2withhmacsha1 makes the inverse process.. and is the same i'm trying to do.. and if you see the keyLength is multiplied by 8 – Andrea Palmate' Oct 20 '16 at 10:55
  • I've found the buily.. but i don't know how to fix it. Basically the salt needs to be decoded from base64 but if i decode it java and nodejs gave me different results since Java use unsigned bytes while nodejs use signed bytes.. How to fix this?? – Andrea Palmate' Oct 20 '16 at 16:58

0 Answers0