digest — один из базовых методов Web Crypto API,
предназначенный для вычисления криптографического хеша от произвольных
данных. Он относится к объекту crypto.subtle и реализует
односторонние хеш-функции, такие как SHA-1, SHA-256, SHA-384 и
SHA-512.
Хеширование в данном контексте — это преобразование входных данных произвольной длины в фиксированную строку байтов, называемую «дайджестом». Результат нельзя обратить обратно в исходные данные, что делает хеш-функции фундаментом для проверки целостности данных, хранения паролей (в связке с другими механизмами), цифровых подписей и множества криптографических протоколов.
crypto.subtle.digest(algorithm, data)
algorithm — строка или объект, определяющий используемую хеш-функцию:
"SHA-1" (устаревший, небезопасный)"SHA-256" (наиболее распространённый)"SHA-384""SHA-512"data — входные данные для хеширования. Должны быть представлены в виде:
ArrayBufferTypedArray (например, Uint8Array)DataViewМетод возвращает Promise, который резолвится в
ArrayBuffer, содержащий бинарный хеш.
Алгоритм digest работает исключительно с байтовыми
данными. Любые строки должны быть предварительно закодированы, чаще
всего в UTF-8 через TextEncoder.
Результат — это «сырые» байты. Для удобства их обычно преобразуют в шестнадцатеричную строку или Base64.
const encoder = new TextEncoder();
const data = encoder.encode("hello world");
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
На этом этапе hashBuffer содержит бинарное представление
хеша.
function bufferToHex(buffer) {
const bytes = new Uint8Array(buffer);
return Array.from(bytes)
.map(b => b.toString(16).padStart(2, "0"))
.join("");
}
Использование:
const encoder = new TextEncoder();
const data = encoder.encode("hello world");
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
const hashHex = bufferToHex(hashBuffer);
console.log(hashHex);
function bufferToBase64(buffer) {
const bytes = new Uint8Array(buffer);
let binary = "";
for (let b of bytes) {
binary += String.fromCharCode(b);
}
return btoa(binary);
}
Ранее широко использовался, но считается криптографически слабым из-за коллизий. Его использование в современных системах не рекомендуется.
Стандарт де-факто. Используется в TLS, блокчейнах, цифровых подписях.
Часть семейства SHA-2 с увеличенной длиной хеша и более высокой криптостойкостью.
digest всегда возвращает Promise, даже
несмотря на то, что операция может выполняться быстро:
const hash = await crypto.subtle.digest("SHA-256", data);
Нельзя передать строку напрямую:
// Ошибка
crypto.subtle.digest("SHA-256", "text");
Корректный вариант:
const data = new TextEncoder().encode("text");
В отличие от encrypt, sign или
deriveKey, метод digest не использует
криптографические ключи. Это чистая односторонняя функция.
Хеш можно использовать для сравнения файлов или сообщений:
const originalHash = await crypto.subtle.digest("SHA-256", data1);
const newHash = await crypto.subtle.digest("SHA-256", data2);
Совпадение хешей означает идентичность данных.
Хеши позволяют быстро определить, изменился ли контент, без побайтового сравнения.
В системах кэширования или распределённых хранилищах хеш используется как идентификатор блока данных.
Частый сценарий — хеширование файла, загруженного пользователем:
async function hashFile(file) {
const buffer = await file.arrayBuffer();
return await crypto.subtle.digest("SHA-256", buffer);
}
digest не поддерживает потоковое обновление. Весь ввод
должен быть доступен сразу. Для больших данных это может быть
ограничением.
Функция не поддерживает соль. Если требуется защита паролей, необходимо комбинировать данные с солью вручную:
const salted = new TextEncoder().encode(password + salt);
const hash = await crypto.subtle.digest("SHA-256", salted);
Хотя Web Crypto API реализован на уровне браузера и обычно использует нативные оптимизации, хеширование больших массивов данных может быть ресурсоёмким.
| Алгоритм | Длина хеша | Статус |
|---|---|---|
| SHA-1 | 160 бит | небезопасен |
| SHA-256 | 256 бит | рекомендован |
| SHA-384 | 384 бит | безопасен |
| SHA-512 | 512 бит | безопасен |
Результат digest — это ArrayBuffer. Он не
содержит строк и не предназначен для прямого отображения. Его структура
— последовательность байтов фиксированной длины, зависящей от
алгоритма.
Пример:
crypto.subtle.digest("SHA-256", "hello"); // ошибка
const hash = crypto.subtle.digest("SHA-256", data);
console.log(hash); // Promise, а не результат
Разные кодировки дают разные хеши. Стандарт — UTF-8:
new TextEncoder().encode("текст");
digest часто используется как вспомогательный этап:
sign (подпись хеша)deriveKey для создания ключей из паролей
(через PBKDF2, где digest играет внутреннюю роль)Метод доступен:
Недоступен:
async function sha256(message) {
const data = new TextEncoder().encode(message);
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
return [...new Uint8Array(hashBuffer)]
.map(b => b.toString(16).padStart(2, "0"))
.join("");
}
Хеш-функции детерминированы: одинаковый вход всегда даёт одинаковый результат, независимо от устройства, времени или окружения.
Результат digest не является «шифром». Он:
Его единственная функция — компактное представление данных с фиксированной длиной и высокой чувствительностью к изменениям входа (эффект лавины).