Как получить хэш SHA-1 на стороне клиента (в браузере)?

Есть текст из которого нужно получить SHA-1.

Например, из строки "Hello World! Привет мир!" нужно получить строку "91e9cbdcbee2b7c7c17b3cd4296c50cd297c543e"

Как, избегая реализации на сервере, получить хэш на стороне клиента?


Ответы (1 шт):

Автор решения: gil9red

Можно использовать стандартный метод crypto.subtle.digest из интерфейса SubtleCrypto.

Поддерживаемые алгоритмы:

  • SHA-1 (не рекомендуется использовать его в криптографических алгоритмах, т.к. считается, что алгоритм теперь уязвим)
  • SHA-256
  • SHA-384
  • SHA-512

Адаптированный пример:

const text = 'Hello World! Привет мир!';

async function digestMessage(message, algo) {
  if (algo == null) {
    algo = "SHA-256";
  }

  const msgUint8 = new TextEncoder().encode(message);                           // encode as (utf-8) Uint8Array
  const hashBuffer = await crypto.subtle.digest(algo, msgUint8);                // hash the message
  const hashArray = Array.from(new Uint8Array(hashBuffer));                     // convert buffer to byte array
  const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join(''); // convert bytes to hex string
  return hashHex;
}

(async function () {
    console.log(await digestMessage(text));
    // fafa2ed466d568ce6893f5fd5c7ef05f3d917cf901e785ff75191a24d5ec83d5

    let digestHex_1 = await digestMessage(text, "SHA-1");
    console.log(digestHex_1);
    // 91e9cbdcbee2b7c7c17b3cd4296c50cd297c543e

    let digestHex_256 = await digestMessage(text, "SHA-256");
    console.log(digestHex_256);
    // fafa2ed466d568ce6893f5fd5c7ef05f3d917cf901e785ff75191a24d5ec83d5

    let digestHex_384 = await digestMessage(text, "SHA-384");
    console.log(digestHex_384);
    // 690b23a3ce2f0cad3b5193b9b76e1632d35dd43eb9498e56affc234c96038b2477aba313b1823965fc614ecc811f08a3

    let digestHex_512 = await digestMessage(text, "SHA-512");
    console.log(digestHex_512);
    // 78be5bf5b01b571af00a7872595793fc6a8a64d7f94c01e2611af08290f202d73758b33039ad5cae789973b8d499d767b58eb9f2d5d8cf12b83bfdcda17f6ca5
})();


Поддержка в браузерах:

введите сюда описание изображения

Однако, есть нюанс с Chrome 60

In Chrome 60, they added a feature that disables crypto.subtle for non-TLS connections

Подробнее на chromium.org:

“Secure origins” are origins that match at least one of the following (scheme, host, port) patterns:

  • (https, *, *)
  • (wss, *, *)
  • (*, localhost, *)
  • (*, 127/8, *)
  • (*, ::1/128, *)
  • (file, *, —)
  • (chrome-extension, *, —)
→ Ссылка