Вычисление HMAC sha-512 в NodeJS и Java

Я пытаюсь перенести вычисление sha-512 с java на node JS, и я не могу получить те же результаты...

Java-код (который выглядит стандартным для что я видел в сети):

public class Test
{
    private static String get_SecurePassword(String passwordToHash, String salt, String algo) throws NoSuchAlgorithmException
    {
        String generatedPassword = null;

        MessageDigest md = MessageDigest.getInstance(algo);
        md.update(salt.getBytes());
        byte[] bytes = md.digest(passwordToHash.getBytes());
        StringBuilder sb = new StringBuilder();

        for (int i = 0; i< bytes.length; i++) {
            sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1));
        }

        generatedPassword = sb.toString();

        return generatedPassword;
    }

    public static void main(String[] args) throws NoSuchAlgorithmException
    {
        String res = get_SecurePassword("test", "test", "SHA-512");

        System.out.println(res);
    }
}

Вывод:

125d6d03b32c84d492747f79cf0bf6e179d287f341384eb5d6d3197525ad6be8e6df0116032935698f99a09e265073d1d6c32c274591bf1d0a20ad67cba921bc

NodeJS:

const crypto = require('crypto');

function getSecurePassword(password, salt, algo) {
    const algoFormatted = algo.toLowerCase().replace('-', '');
    const hash = crypto.createHmac(algoFormatted, salt);
    hash.update(password);

    const res = hash.digest('hex');

    return res;
}

console.info(getSecurePassword('test', 'test', 'SHA-512'));

Вывод:

9ba1f63365a6caf66e46348f43cdef956015bea997adeb06e69007ee3ff517df10fc5eb860da3d43b82c2a040c931119d2dfc6d08e253742293a868cc2d82015

Что я делаю неправильно?

Примечание: Я использую Java 8 и Node 10.13.

Ваш результат NodeJS является правильным в соответствии с Freeformatter.

RaminS 29.01.2019 19:59

Вы звоните getBytes() без указания кодировки символов. В зависимости от ваших данных и кодировки платформы по умолчанию в вашей системе это может изменить то, что вы передаете для соли и открытого текста.

David Conrad 29.01.2019 20:01

Ооо... Значит, Java-код не является стандартным sha-512? если да, то как я могу повторить это? @Жандарм

Tomer Amir 29.01.2019 20:02

Спасибо @DavidConrad, я попытался добавить кодировку в код Java, но это не помогло (оба кода запускались в одной системе)

Tomer Amir 29.01.2019 20:02
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
4
2 676
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

В Node вы используете HMAC-SHA-512, но в Java вы просто используете SHA-512 и объединяете ключ и открытый текст. HMAC работает не так. Вам также необходимо использовать HMAC-SHA-512 в Java:

import static java.nio.charset.StandardCharsets.*;

import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

public class Test {
    private static String getSecurePassword(String password, String salt, String algo)
            throws NoSuchAlgorithmException, InvalidKeyException {
        SecretKeySpec secretKeySpec = new SecretKeySpec(salt.getBytes(UTF_8), algo);
        Mac mac = Mac.getInstance(algo);
        mac.init(secretKeySpec);
        byte[] bytes = mac.doFinal(password.getBytes(UTF_8));

        return new BigInteger(1, bytes).toString(16);
    }

    public static void main(String[] args)
            throws NoSuchAlgorithmException, InvalidKeyException {
        System.out.println(getSecurePassword("test", "test", "HmacSHA512"));
    }
}

Вывод:

9ba1f63365a6caf66e46348f43cdef956015bea997adeb06e69007ee3ff517df10fc5eb860da3d43b82c2a040c931119d2dfc6d08e253742293a868cc2d82015

На самом деле мне нужно было наоборот (чтобы исправить код JS), но это помогло! :) Благодарность!!!

Tomer Amir 29.01.2019 20:36

Если кто-то ищет исправление Node JS, которое я сделал благодаря @DavidConrad, вот оно:

const crypto = require('crypto');

function getSecurePassword(password, salt, algo) {
    const algoFormatted = algo.toLowerCase().replace('-', '');
    const hash = crypto.createHash(algoFormatted);
    hash.update(salt + password);

    return hash.digest('hex');
}

console.info(getSecurePassword('test', 'test', 'SHA-512'));

Вывод:

125d6d03b32c84d492747f79cf0bf6e179d287f341384eb5d6d3197525ad6be8e6df0116032935698f99a09e265073d1d6c32c274591bf1d0a20ad67cba921bc

Для NodeJS вы можете добавить ключ с данными, чтобы получить хэш, эквивалентный Ява.

require('crypto').createHash(algo).update(data + key).digest()

Другие вопросы по теме