0

I have a Java code like below that encrypt passwords. I try to convert it to Javascript but got that error:

Error [ERR_CRYPTO_HASH_FINALIZED]: Digest already called

I found some similar questions and answers say; put hash.update() in your for but so result will be different than Java.

How can I fix this? How can i get same result with Java in Javascript? :/

Java

public String encryptNew(String password, String salt) throws IOException, NoSuchAlgorithmException {
    byte[] saltBytes = base64ToByte(salt);
    byte[] encryptedBytes = getHash(password, saltBytes);
    String result = byteToBase64(encryptedBytes);
    return result;
}

private byte[] getHash(String password, byte[] salt) throws NoSuchAlgorithmException,                 
UnsupportedEncodingException {
    MessageDigest digest = MessageDigest.getInstance("SHA-512");
    digest.reset();
    digest.update(salt);
    byte[] input = digest.digest(password.getBytes("UTF-8"));
    for (int i = 0; i < 1000; i++) {
        digest.reset();
        input = digest.digest(input);
    }
    return input;
}

My Javascript

const pass = '12344321';
const salt = 'X9geKit5sd0=';
// 1. ToByte
const saltBytes = Buffer.from(salt, 'base64');
console.log('Salt:', saltBytes);
// 2. Hash
let hash = crypto.createHash('sha512');
hash.update(saltBytes);
var input = new TextEncoder();
input.encode(pass);
for (let i = 0; i < 1000; i++) {
  input = hash.digest(input);
}
// 3. ToBase64
const result = Buffer.from(input).toString('base64');
console.log('Result:', result);

1 Answer 1

2

The signature of the methods of a Hash object in node.js is totally different compared to MessageDigest in Java. You can only feed data into it through update. Since there is no reset, you need to use a fresh Hash instance everytime.

Here is the full code which produces your expected result:

let crypto = require('crypto');

const pass = '12344321';
const salt = 'X9geKit5sd0=';
// 1. ToByte
const saltBytes = Buffer.from(salt, 'base64');

// 2. Hash
let hash = crypto.createHash('sha512');
hash.update(saltBytes);
hash.update(Buffer.from(pass, 'utf8'));
let input = hash.digest();
for (let i = 0; i < 1000; i++) {
  hash = crypto.createHash('sha512');
  hash.update(input);
  input = hash.digest();
}
// 3. ToBase64
const result = Buffer.from(input).toString('base64');
console.log('Result:', result);

Keep in mind that this hashes your password in a quick way where the salt is only used for the first iteration. It is better to use established password hashing methods such as Argon2, scrypt, bcrypt or PBKDF2 with a high work factor.

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

Comments

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.