Функция Math.random() долгое время использовалась как
универсальный источник случайных чисел в JavaScript-приложениях. Она
возвращает значение в диапазоне от 0 до 1, создавая иллюзию случайности,
достаточной для большинства прикладных задач интерфейса и логики.
Однако ключевая проблема заключается в природе самого генератора: это псевдослучайный алгоритм, детерминированный по своей сути. Он не предназначен для криптографических задач и не выдерживает атак, направленных на восстановление внутреннего состояния генератора.
Главные ограничения Math.random():
В контексте безопасности это означает, что любые механизмы,
основанные на Math.random(), могут быть скомпрометированы.
Генерация токенов, ключей, одноразовых паролей или CSRF-защит с его
использованием создаёт фундаментальную уязвимость.
Пример небезопасного подхода:
const token = Math.random().toString(36).substring(2);
Даже при внешней “достаточной случайности” такой токен может быть восстановлен или предсказан при наличии достаточного числа наблюдений.
Функции btoa() и atob() часто ошибочно
воспринимаются как инструменты шифрования. На практике они реализуют
только кодирование и декодирование Base64.
Base64 — это способ представления бинарных данных в текстовом виде, а не механизм защиты информации.
Ключевые особенности:
Пример типичного заблуждения:
const encoded = btoa("secret-password");
const decoded = atob(encoded);
Полученный результат не является защищённым ни в каком смысле. Любой,
кто получил строку encoded, мгновенно восстанавливает
исходные данные.
Часто btoa/atob ошибочно используют для:
Во всех этих случаях создаётся лишь иллюзия безопасности, не имеющая криптографической основы.
До появления зрелой реализации Web Crypto API в браузерах широко использовались сторонние библиотеки:
Их появление было реакцией на отсутствие встроенных криптографических средств в браузере.
Особенно критичным фактором является реализация криптографии на уровне интерпретируемого JavaScript. Даже при корректном алгоритме производительность и безопасность зависят от движка и отсутствия утечек через тайминги.
Web Crypto API стал стандартизированным ответом браузеров на необходимость встроенной криптографии. В отличие от предыдущих подходов, он предоставляет нативные реализации криптографических операций, изолированные от JavaScript-слоя.
Ключевое отличие — работа через низкоуровневые системные реализации, а не через пользовательский код.
Вместо Math.random() используется:
const array = new Uint8Array(16);
crypto.getRandomValues(array);
Этот метод:
Вместо сторонних библиотек:
const data = new TextEncoder().encode("message");
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
Особенности:
Web Crypto API предоставляет доступ к алгоритмам вроде AES-GCM:
const key = await crypto.subtle.generateKey(
{ name: "AES-GCM", length: 256 },
true,
["encrypt", "decrypt"]
);
const iv = crypto.getRandomValues(new Uint8Array(12));
const encoded = new TextEncoder().encode("secret data");
const encrypted = await crypto.subtle.encrypt(
{ name: "AES-GCM", iv },
key,
encoded
);
В отличие от сторонних библиотек:
Web Crypto API поддерживает RSA-OAEP и ECDSA:
const keyPair = await crypto.subtle.generateKey(
{
name: "RSA-OAEP",
modulusLength: 2048,
publicExponent: new Uint8Array([1, 0, 1]),
hash: "SHA-256"
},
true,
["encrypt", "decrypt"]
);
Это позволяет:
Исторически JavaScript развивался от полного отсутствия криптографических инструментов к нативной интеграции в браузер.
Math.random() — псевдослучайность для UI и логикиbtoa/atob — кодирование данных без защитыФундаментальное изменение заключается в переносе ответственности: от разработчика и библиотек к платформе и операционной системе.
Использование устаревших методов приводит к системным проблемам:
Особенно критично это проявляется в:
Переход к Web Crypto API фактически меняет модель доверия:
Это снижает поверхность атаки и уменьшает вероятность ошибок, связанных с реализацией криптографии на уровне приложения.