Алгоритм SHA-1 (Secure Hash Algorithm 1) относится к классу криптографических хеш-функций и был разработан в 1995 году Национальным институтом стандартов и технологий США (NIST). Его задача — преобразование входных данных произвольной длины в фиксированную строку длиной 160 бит (20 байт), называемую хешем или дайджестом.
Основные свойства, которыми должен обладать криптографический хеш:
SHA-1 долгое время считался надёжным и широко применялся в:
Алгоритм обрабатывает данные блоками по 512 бит и использует итеративную структуру:
Дополнение сообщения (padding) Сообщение расширяется до длины, кратной 512 битам, с добавлением единицы, нулей и длины исходного сообщения.
Инициализация буфера Используются пять 32-битных регистров:
H0, H1, H2, H3, H4Обработка блоков Каждый блок проходит 80 раундов преобразований с использованием побитовых операций:
Формирование итогового хеша После обработки всех блоков значения регистров объединяются в 160-битный результат.
Библиотека CryptoJS предоставляет простый интерфейс для вычисления SHA-1:
const hash = CryptoJS.SHA1("Hello, world!");
console.log(hash.toString());
Работа с кодировками:
const hashHex = CryptoJS.SHA1("Hello").toString(CryptoJS.enc.Hex);
const hashBase64 = CryptoJS.SHA1("Hello").toString(CryptoJS.enc.Base64);
Хеширование бинарных данных:
const wordArray = CryptoJS.lib.WordArray.create([0x12345678]);
const hash = CryptoJS.SHA1(wordArray);
Со временем выяснилось, что SHA-1 не удовлетворяет современным требованиям безопасности.
Коллизия — это ситуация, когда:
hash(A) = hash(B), при A ≠ B
Для SHA-1 теоретическая сложность нахождения коллизии составляет (2^{80}), однако практические атаки значительно снизили этот порог.
Ключевые этапы компрометации:
В рамках SHAttered были созданы два разных PDF-файла с одинаковым SHA-1 хешем.
Современные вычислительные мощности позволяют находить коллизии за приемлемое время и стоимость.
Если злоумышленник может подобрать два документа с одинаковым хешем:
то подпись первого может быть использована для второго.
160 бит недостаточно для современных требований. Для сравнения:
Организации и протоколы начали запрещать SHA-1:
Идея атаки:
Создаются два разных сообщения:
M1 ≠ M2Подбираются так, чтобы:
SHA1(M1) = SHA1(M2)Одно сообщение проходит проверку, другое используется злоумышленником.
На практике это достигается сложными математическими методами и требует значительных вычислительных ресурсов, но уже не является недостижимым.
Использование SHA-1 считается небезопасным в следующих случаях:
Допустимое применение:
Наиболее распространённая замена:
const hash = CryptoJS.SHA256("Hello");
Преимущества:
Новый стандарт, основанный на другой конструкции (Keccak):
const hash = CryptoJS.SHA3("Hello", { outputLength: 256 });
Современные быстрые хеш-функции, не входящие в CryptoJS, но активно используемые в индустрии.
CryptoJS продолжает поддерживать SHA-1 по следующим причинам:
Однако при разработке новых приложений:
| Характеристика | SHA-1 | SHA-256 |
|---|---|---|
| Длина хеша | 160 бит | 256 бит |
| Устойчивость | Нарушена | Высокая |
| Коллизии | Найдены | Неизвестны |
| Скорость | Быстрее | Немного медленнее |
| Рекомендуется | Нет | Да |
Было:
const hash = CryptoJS.SHA1(password);
Стало:
const hash = CryptoJS.SHA256(password);
Для усиления безопасности паролей:
const hash = CryptoJS.PBKDF2(password, salt, {
keySize: 256/32,
iterations: 1000
});
Игнорирование этих факторов приводит к уязвимостям даже при корректной реализации кода