SHA-1 (Secure Hash Algorithm 1) — криптографическая хеш-функция,
преобразующая произвольный входной набор данных в 160-битное (20 байт)
хеш-значение. В контексте Web Crypto API используется через интерфейс
SubtleCrypto, предоставляющий асинхронные методы для
криптографических операций.
Метод digest позволяет вычислить хеш:
const data = new TextEncoder().encode("example");
const hashBuffer = await crypto.subtle.digest("SHA-1", data);
const hashArray = Array.from(new Uint8Array(hashBuffer));
const hashHex = hashArray.map(b => b.toString(16).padStart(2, "0")).join("");
console.log(hashHex);
Особенности:
ArrayBuffer или TypedArrayArrayBufferPromise)SHA-1 исторически считалась безопасной благодаря следующим свойствам:
Однако ключевая проблема — нарушенная коллизионная устойчивость.
Коллизия — ситуация, при которой два различных входа дают одинаковый хеш.
В 2017 году была продемонстрирована практическая атака (SHAttered), доказавшая возможность генерации коллизий для SHA-1 с разумными вычислительными затратами.
Это означает:
Несмотря на уязвимости, SHA-1 остаётся доступной:
crypto.subtle.digest("SHA-1", data);
Поддерживается во всех современных браузерах, но с ограничениями в некоторых сценариях (например, сертификаты TLS).
Пример:
// генерация ключа для кеша
const key = await crypto.subtle.digest("SHA-1", data);
Некоторые протоколы и API требуют SHA-1:
При отсутствии атакующей модели (например, локальные инструменты разработки)
Использование SHA-1 в подписях (например, RSA-PKCS1-v1_5 с SHA-1):
crypto.subtle.sign(
{ name: "RSASSA-PKCS1-v1_5" },
privateKey,
data
);
Недопустимо, если используется SHA-1:
Любые случаи, где данные могут быть подменены:
SHA-1 категорически не подходит:
Вместо этого:
Современные браузеры:
await crypto.subtle.digest("SHA-256", data);
Используются при повышенных требованиях безопасности:
await crypto.subtle.digest("SHA-512", data);
| Свойство | SHA-1 | SHA-256 |
|---|---|---|
| Размер хеша | 160 бит | 256 бит |
| Коллизионная стойкость | Нарушена | Надёжна |
| Производительность | Быстрее | Немного медленнее |
| Безопасность | Устарела | Современная |
crypto.subtle.digest("SHA-1", data);
Причина — историческое распространение, а не актуальная безопасность.
SHA-1 может быть безопасна в одном контексте и критически уязвима в другом.
Любой новый код с SHA-1 — потенциальный технический долг.
Рекомендуется явно задавать алгоритм и избегать неявных значений:
const algorithm = "SHA-256"; // вместо SHA-1
Было:
await crypto.subtle.digest("SHA-1", data);
Стало:
await crypto.subtle.digest("SHA-256", data);
SHA-1 немного быстрее, но:
SHA-1 может применяться в HMAC, но также нежелательна:
await crypto.subtle.importKey(
"raw",
keyData,
{ name: "HMAC", hash: "SHA-1" },
false,
["sign"]
);
Рекомендуется:
{ name: "HMAC", hash: "SHA-256" }
SHA-1 — инструмент прошлого, допустимый только в условиях строгой необходимости совместимости и отсутствия угроз. В любых сценариях, связанных с безопасностью, должен быть полностью исключён.