简体   繁体   中英

Converting Java Encryption to Javascript with NodeJs Crypto

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);

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM