Converting a hash from Java to Javascript

Viewed 278

I'm trying to convert a hash function originally written in Java to Javascript in our codebase. However, I am getting different results. Below is the code in Java

public static String hashText(String str) {
    MessageDigest messageDigest;
    try {
        messageDigest = MessageDigest.getInstance("SHA-512");
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
        messageDigest = null;
    }
    byte[] bytes = str.getBytes();
    for (int i = 0; i < 64; i++) {
        messageDigest.update(bytes);
        bytes = messageDigest.digest();
    }
    hashedText = new String(Base64.encode(bytes, 2));
    return hashedText.replace(StringUtils.LF, "");
}

And here is what I wrote in Javascript

function hashText(text){
  const crypto = require('crypto')
  const hash = crypto.createHash('sha512');
  const digest = hash.update(text).digest();
  return digest.toString("base64")
}
console.log(hashText(text))

I've been trying to figure out what I am doing wrong here but no success yet. I need help!

2 Answers

That for loop in the java, it looks like it's rehashing the hash 64 times. Looks like you're only hashing once in JavaScript. Here's an example of how you might do that loop in node.js.

function hashText(text, iter = 1) {
  const crypto = require('crypto');
  let digest = text;
  for (let i = 0; i < iter; i++) {
    const hash = crypto.createHash('sha512');
    digest = hash.update(digest).digest();
  }
  return digest.toString('base64');
}
const text = 'asdf 1234 zxcv 5678';
console.log(hashText(text, 64));

*Edit: I don't use java, didn't know how MessageDigest.digest(), worked. Specifically:

... The digest is reset after this call is made.

In node, this means running createHash every iteration of the loop. Thanks @dave_thompson_085 for pointing this out!

It turns out the way nodejs crypto hash copy works is kinda different. As stated in the docs, it creates a new Hash object that contains a deep copy of the internal state of the current Hash object. However, what I need is to create a new hash with the encoded string.

Below is a sample of a working snippet

function hashText(text, length) {
  const crypto = require('crypto');
  let digest = text;
  for (let i = 0; i < length; i++) {
    const hash = crypto.createHash('sha512');
    hash.update(digest);
    digest = hash.digest();
  }

  return digest.toString('base64');
}
console.log(hashText(text, 64));

Thanks to everyone that helped one way or the other

Related