В библиотеке Stanford JavaScript Crypto Library работа с цифровыми подписями основана на асимметричных алгоритмах, чаще всего ECDSA (Elliptic Curve Digital Signature Algorithm). Подпись используется для подтверждения того, что сообщение действительно создано владельцем приватного ключа и не было изменено после подписания.
Проверка подписи (signature verification) — это операция, которая позволяет убедиться в двух ключевых свойствах:
Для работы с подписями в SJCL используются следующие элементы:
В SJCL ключи обычно представлены в формате объектов или сериализованных JSON-структур.
ECDSA основан на математике эллиптических кривых. Его ключевая идея заключается в том, что:
Подпись состоит из двух чисел:
Оба значения формируются на основе хэша сообщения и случайного числа (nonce), которое должно быть уникальным для каждой подписи.
Перед проверкой подписи необходимо иметь корректно сформированные ключи.
Пример генерации пары ключей:
var keypair = sjcl.ecc.elGamal.generateKeys(256);
var pub = keypair.pub;
var priv = keypair.sec;
Публичный ключ используется на стороне проверки, приватный — на стороне подписи.
Подпись создаётся приватным ключом:
var message = "hello world";
var hash = sjcl.hash.sha256.hash(message);
var signature = priv.sign(hash);
Важно понимать, что SJCL не подписывает строку напрямую — сначала вычисляется хэш сообщения.
Подпись обычно хранится в сериализованном виде:
var sigJson = sjcl.codec.json.fromBits(signature);
Это позволяет передавать подпись по сети или сохранять в базе данных.
Процесс проверки выполняется с использованием публичного ключа.
var message = "hello world";
var hash = sjcl.hash.sha256.hash(message);
var sig = sjcl.codec.json.toBits(sigJson);
var valid = pub.verify(hash, sig);
Если подпись корректна, переменная valid будет равна
true.
Критическая ошибка в криптографии ECDSA — повторное использование nonce. Если одно и то же случайное число используется для разных сообщений, приватный ключ может быть восстановлен.
SJCL автоматически генерирует nonce, но при кастомных реализациях важно избегать ручного вмешательства.
SJCL не выполняет скрытое хэширование внутри функции подписи. Это означает:
При работе с SJCL важно соблюдать совместимость форматов:
Любое несоответствие форматов приводит к ложному отрицанию подписи.
Если подпись создавалась с SHA-256, а проверка выполняется с другим алгоритмом — результат всегда будет false.
Даже изменение одного символа полностью меняет хэш:
Частая ошибка:
Типичный сценарий:
var data = response.data;
var signature = response.signature;
var hash = sjcl.hash.sha256.hash(data);
var sigBits = sjcl.codec.base64.toBits(signature);
var isValid = serverPubKey.verify(hash, sigBits);
В системах авторизации подписи используются для JWT-подобных токенов:
Метод:
pub.verify(hash, signature)
выполняет следующие шаги:
Проверка подписи в SJCL:
SJCL полностью совместима с браузерной средой:
if (pub.verify(hash, sig)) {
console.log("подпись корректна");
} else {
console.log("подпись недействительна");
}
Проверка выполняется синхронно и не требует серверной логики.
Подписи SJCL не всегда совместимы с внешними библиотеками без преобразования:
Проверка подписи в SJCL строится на принципе:
Это делает систему устойчивой к MITM-атакам при корректной реализации ключевого обмена.
Метод verify() всегда возвращает:
true — подпись совпадаетfalse — подпись невалиднаИсключения не выбрасываются, что упрощает обработку в продуктивных системах.
SJCL позволяет проверять несколько подписей для одного сообщения: