Конвертировать функцию HMAC-SHA384 из Java в JavaScript - PullRequest
1 голос
/ 21 ноября 2019

Это java-функция, которая выполняет эту работу.

 static byte[] HmacSHA384(String data, byte[] key) {
    try {
        mac.init(new SecretKeySpec(key, HMAC_ALGORITHM));
    } catch (InvalidKeyException e) {
        //throw new PWAINUnRecoverableException("Invalid key exception while mac init", e);
        throw new RuntimeException("Invalid key exception while mac init", e);
    }
    return mac.doFinal(data.getBytes(StandardCharsets.UTF_8));
}

Я уже попробовал этот ответ безуспешно.

Используется crypto-js модультакже как:

const result = crypto_js.HmacSHA384(key, data).toString();
console.log(result.split('').map(getBytes)); // used this to match byte array from java output. No luck!
function getBytes(x) {return x.charCodeAt(0);}

Обратите внимание, что я использую key в качестве строки в коде JavaScript, так как crypto_js.HmacSHA384 принимает только строку, а не byte[]. Но я сравнил byte[] моей строки с byte[].

в Java-коде. Вывод из кода JS:

[97,104,69,80,106,49,121,83,100,87,120,56,76,65,101,71,54,52,81,110,104,108,72,55,54,56,112,104,56,109,72,101,68,43,83,70,73,89,54,81,71,53,49,98,48,119,115,117,72,83,112,117,99,110,107,76,113,78,105,73,76,107,120,82]

Вывод из кода Java:

[-29, 76, -16, -110, -35, -87, 18, -53, -1, -105, -77, -96, -49, -110, 102, -74, -110, 31, -87, 115, 102, -43, 101, -89, -82, -8, 96, -99, -89, 103, -128, 104, -121, -107, -98, 18, -18, 85, 97, -121, 30, 91, -42, -11, -6, -58, -7, 113]

Оба требуют одинакового ввода.

Любая помощь будет оценена. Спасибо!

1 Ответ

3 голосов
/ 21 ноября 2019

В JavaScript не так просто вывести необработанные байты. Подробности см. В ответе https://stackoverflow.com/a/29433028/7873775.

Но байтовые массивы будут по-прежнему отличаться в Java и JavaScript, поскольку в JavaScript Uint8Array представляет массив 8-битных целых чисел без знака в то время как в Java * диапазон 1008 * составляет от -128 до 127.

То есть Uint8Array [132, 179] в Java byte[] равно [-124, -77].

Для вывода HMACЗначение в JavaScript необходимо кодировать в шестнадцатеричном или Base64.

Вот код Java с использованием commons-codec library:

byte[] key = "Secret Passphrase".getBytes(StandardCharsets.UTF_8);
String valueToDigest = "Message";
byte[] hmac = new HmacUtils(HMAC_SHA_384, key).hmac(valueToDigest);
System.out.println(asList(hmac));
System.out.println(Hex.encodeHexString(hmac));
System.out.println(Base64.encodeBase64String(hmac));

Результат:

  • Hex: 84b318cc0232a370c1f8b8746afcb575fc2debc680122c7422fd425638896d0dcf9e905b8cd9c1d7aed8d5439a2a2328
  • Base64: hLMYzAIyo3DB+Lh0avy1dfwt68aAEix0Iv1CVjiJbQ3PnpBbjNnB167Y1UOaKiMo

Вот код с CryptoJS библиотека:

const CryptoJS = require("crypto-js");
const hash = CryptoJS.HmacSHA384("Message", "Secret Passphrase");
console.log(hash.toString(CryptoJS.enc.Hex));
console.log(hash.toString(CryptoJS.enc.Base64));

И результат идентичен :

  • Hex: 84b318cc0232a370c1f8b8746afcb575fc2debc680122c7422fd425638896d0dcf9e905b8cd9c1d7aed8d5439a2a2328
  • Base64: hLMYzAIyo3DB+Lh0avy1dfwt68aAEix0Iv1CVjiJbQ3PnpBbjNnB167Y1UOaKiMo
...