scrypt в SJCL используется как функция вывода ключа (KDF), предназначенная для получения криптографически стойких ключей из паролей с защитой от атак перебором и специализированного оборудования. Основное отличие scrypt от более простых KDF (например, PBKDF2) заключается в высокой требовательности к памяти, что делает массовый перебор существенно дороже по ресурсам.
Библиотека SJCL не всегда включает scrypt в базовую сборку. Модуль может подключаться отдельно, так как относится к более тяжёлым криптографическим операциям.
Обычно структура подключения выглядит так:
<script src="sjcl.js"></script>
<script src="sjcl-scrypt.js"></script>
После подключения расширения становится доступен интерфейс:
sjcl.misc.scrypt
Ключевой момент: без подключения дополнительного модуля вызов функции будет недоступен.
Функция scrypt в SJCL вызывается следующим образом:
sjcl.misc.scrypt(password, salt, N, r, p, dkLen)
Параметры:
Результат возвращается в формате bitArray, используемом
внутри SJCL для всех криптографических операций.
var password = "secure-password";
var salt = "random-salt";
var derivedKey = sjcl.misc.scrypt(password, salt, 16384, 8, 1, 32);
var hexKey = sjcl.codec.hex.fromBits(derivedKey);
console.log(hexKey);
В этом примере:
N = 16384 задаёт умеренную стойкость и нагрузкуr = 8 и p = 1 используются как стандартный
балансdkLen = 32 формирует 256-битный ключN = 2^k
Значение N определяет базовую сложность алгоритма. Увеличение N экспоненциально повышает затраты памяти и времени. Например:
Параметр r увеличивает размер внутренних блоков памяти. Рост r линейно увеличивает потребление RAM, усиливая защиту от GPU/ASIC атак.
p определяет количество параллельных потоков вычислений. В большинстве JS-реализаций значение p чаще всего оставляют равным 1, так как увеличение приводит к значительному росту CPU-нагрузки в браузере.
SJCL оперирует внутренним типом bitArray, поэтому для
дальнейшего использования ключ часто преобразуется:
var hex = sjcl.codec.hex.fromBits(derivedKey);
var base64 = sjcl.codec.base64.fromBits(derivedKey);
Частые сценарии:
scrypt обычно применяется как этап генерации ключа для симметричного шифрования:
var key = sjcl.misc.scrypt("password", "salt", 16384, 8, 1, 32);
var cipher = new sjcl.cipher.aes(key);
var encrypted = sjcl.encrypt("password", "секретное сообщение", {
mode: "gcm"
});
В реальных сценариях ключ из scrypt передаётся напрямую в AES без промежуточных строковых преобразований.
scrypt в JavaScript является ресурсоёмкой операцией. В SJCL он выполняется синхронно, что означает блокировку основного потока выполнения.
Практические последствия:
Типичный диапазон для браузера:
Баланс между безопасностью и производительностью определяется целевым сценарием:
Ключевой принцип заключается в том, что увеличение параметров должно учитывать не только криптографическую стойкость, но и допустимую задержку интерфейса.
Соль должна быть уникальной для каждого пароля:
var salt = sjcl.random.randomWords(4, 0);
Использование криптографически стойкой генерации случайных значений критично, так как повторяющиеся salt полностью обесценивают защиту scrypt.
SJCL также содержит PBKDF2, который проще в вычислении:
В сценариях, где важна устойчивость к специализированному железу, scrypt предпочтительнее.
Часто встречающиеся проблемы:
SJCL использует bitArray как основной тип:
Работа напрямую со строками без кодеков приводит к ошибкам интерпретации ключей.
При использовании scrypt в веб-приложениях с SJCL обычно применяют следующую архитектуру:
Такая схема исключает необходимость хранения пароля в явном виде и снижает риск компрометации при утечках данных на сервере.