0

I've been strugling for a while now by trying to complete next goal : I have a "Reset password" page that supposed to send new password to the server. I would like to hash it with salt, so I could save it in DB eventually. On Server side I have next methods that creates password hash :

public static String makeHash(String password, String salt) {
    try {
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        md.update(password.getBytes("UTF-8"));

        byte byteData[] = md.digest(makeHash(salt.toLowerCase()));

        return Base64.getEncoder().encodeToString(byteData);
    } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
        log.error("Unable to make hash for pass. No hashing.", e);
    }

    return password;
}

private static byte[] makeHash(String val) throws NoSuchAlgorithmException, UnsupportedEncodingException {
    return MessageDigest.getInstance("SHA-256").digest(val.getBytes("UTF-8"));
}

I tried several Javascript libraries - crypto, crypto-js, SJCL , but couldn't manage to create same password as Java methods generates. For example, last working try out was :

var crypto = require('crypto');
crypto.pbkdf2('123', '[email protected]', 1000, 60, 'sha256', function(err, key) {
  if (err)
    throw err;
  console.log(key.toString('Base64'));  // 'c5e478d...1469e50'
});

And it generated me this hash - Qr2lzotlRWj7BeJeFooMRj64auMPTb3PRhwLmfNcl4DCVAlFFibgOqZiyExZNO5i/icAUYoMjy73jSTd, while Java gives me - /pyQf3JCj5XoczfsYJ4LUb+y0DONGMl/AFzLiBTo8LA=.

I cannot change backend, since it running already for some time, so I was hoping that maybe someone could help me out with this.

1 Answer 1

3

You have to use the same algorithm on both sides. In Java you're using simply SHA-256 and in node you're using PBKDF2 with SHA-256.

Node.js' crypto module provides the createHash(algorithm) function. Where you can specify SHA-256 directly. PBKDF2 is an algorithm that only uses different hashing functions under the hood.

If you want hash passwords, then it is much safer to use PBKDF2 with a lot of iterations (> 86,000) and a random salt that you store alongside the password hash.

Java has support for PBKDF2 in its standard library.

If you really want to use SHA-256 directly and I strongly advise against it, you can use the following code:

var crypto = require('crypto');
var key = "123";
var salt = "[email protected]";

key = crypto.createHash('sha256')
        .update(key, "utf8")
        .update(makeHash(salt))
        .digest("base64");

console.log(key);

function makeHash(val) {
    return crypto.createHash('sha256').update(val, "utf8").digest();
}

Output:

/pyQf3JCj5XoczfsYJ4LUb+y0DONGMl/AFzLiBTo8LA=

Note that Hash.digest() takes an optional output encoding and not additional data.

Sign up to request clarification or add additional context in comments.

3 Comments

I tried to create hash with SHA-256 algorithm like this - gist.github.com/azakordonets/e436ccbdb2a4aedac52a and try to imitate Java approach, but i failed. As a result i was getting JUE2ZSVBNFklMjBCLyU5REElN0VIZyVFRiVEQ08lQjglQTBKJTFGJTNGJUZGJTFGJUEwJTdFJTk5JThFJTg2JUY3JUY3JUEyeiVFMw==
Added full code example, but I strongly advise against using SHA-256 directly for hashing passwords.
Thanks a lot. I missed one littel thing and was so close - you saved a lot of my time :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.