Skip to content

SM3 — хеш и HMAC ​

SM3 — китайский национальный алгоритм хеширования (GM/T 0004-2012): дайджест 256 бит при блоке 512 бит, применяется там же, где SHA-256. Реализация работает в sm3.wasm.

  • Длина блока 512 бит, длина дайджеста 256 бит;
  • Вход — произвольная битовая строка, включая пустую (l = 0);
  • hmac — это HMAC-SM3 по RFC 2104 с блоком 64 байта.

Импорт ​

ts
import { sm3 } from 'sm-crypto-wasm';

await sm3.ensureLoaded();   // прогрев один раз; всё дальше — синхронно

API ​

Прогрев WASM sm3.ensureLoaded() ​

ts
function ensureLoaded(): Promise<void>

Загружает и создаёт экземпляр sm3.wasm. Один await обязателен до hash / hmac. Повторные вызовы дешёвы (мемоизация на уровне модуля, конкурентные вызовы делят один Promise).

Хеширование sm3.hash(input) ​

ts
function hash(input: string | Uint8Array): string
ПараметрТипОбязателенОписание
inputstring | Uint8Arrayдасообщение для хеширования

Если input — строка, её кодировка определяется в таком порядке:

Начало строкиСчитается
начинается с -----BEGINPEM
есть префикс 0x или строка целиком из [0-9a-fA-F] чётной длиныhex
любая другая строка, которую декодирует atobbase64

Возвращает 32-байтный дайджест в hex (строчные буквы, 64 символа).

Граница: пустой вход трактуется как сообщение нулевой длины — это не ошибка. Для пустой строки у SM3 есть однозначный результат. Если хотите, чтобы пропущенный аргумент падал громко, проверяйте его сами.

HMAC sm3.hmac(key, msg) ​

ts
function hmac(key: string | Uint8Array, msg: string | Uint8Array): string
ПараметрТипОбязателенОписание
keystring | Uint8Arrayдалюбой длины; длиннее 64 байт сначала хешируется
msgstring | Uint8Arrayдасообщение

Возвращает 32-байтный HMAC в hex. Оба параметра распознаются так же, как в hash.

Использование ​

ts
import { sm3 } from 'sm-crypto-wasm';

await sm3.ensureLoaded();

// байты UTF-8 от строки 'abc'
sm3.hash(new TextEncoder().encode('abc'));
// → '66c7f0f4 62eeedd9 d1f2d46b dc10e4e2 4167c487 5cf2f7a2 297da02b 8f4ba8e0' (пробелы убраны)

// hex-ввод разбирается побайтово — результат тот же
sm3.hash('616263');

// пустая строка
sm3.hash('');

// HMAC-SM3 (RFC 2104)
sm3.hmac('00112233445566778899aabbccddeeff', '616263');

Строка — это не «текст»

sm3.hash('abc') не хеширует текст abc в UTF-8: строка проходит распознавание, 'abc' не является корректным hex, поэтому срабатывает ветка base64 (2 байта). Чтобы хешировать текст, кодируйте его явно через new TextEncoder().encode(text) или передайте hex-строку.

Playground ​

Виджет ниже загружает sm3.wasm прямо в браузере и считает по-настоящему, это не запись готового вывода. Вариант utf8 в списке кодировок — это ровно new TextEncoder().encode(text).

SM3: хеш и HMAC-SM3

WASM · live

Нажатие «Запустить» загружает sm3.wasm и реально считает hash и hmac по указанному выше сообщению.

sm3.hash(msg)—
sm3.hmac(key, msg)—
Эквивалентный код
import { sm3 } from 'sm-crypto-wasm';

await sm3.ensureLoaded();          // один раз прогреваем wasm (асинхронно)
sm3.hash('abc');                   // → 32-байтный хеш в hex
sm3.hmac(key, 'abc');              // → 32-байтный HMAC в hex

См. также ​

  • SM4 — режим GCM использует SM4 + GHASH и от SM3 не зависит;
  • SM2 — подпись по умолчанию SM3withSM2, значение Z считается через SM3;
  • SM9 — вывод пользовательских ключей использует KDF и HMAC на SM3.

Лицензия Apache-2.0