Библиотека Jsrsasign поддерживает основные форматы представления
ключей, используемые в веб-криптографии:
PEM (Privacy-Enhanced Mail) Текстовый формат,
кодированный Base64 и обрамлённый служебными заголовками:
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----
Преимущества:
- удобство хранения и передачи
- читаемость Недостатки:
- повышенный риск утечки при неосторожном обращении
DER (Distinguished Encoding Rules) Бинарный формат
ASN.1:
- более компактный
- сложнее для анализа человеком
- используется при работе с сертификатами и низкоуровневыми API
JWK (JSON Web Key) JSON-структура:
{
"kty": "RSA",
"n": "...",
"e": "AQAB",
"d": "..."
}
Преимущества:
- нативная интеграция с JavaScript
- удобство передачи через API Недостатки:
- требует строгого контроля доступа
Загрузка и
инициализация ключей в Jsrsasign
Основной класс для работы с ключами — KEYUTIL.
Загрузка приватного ключа из PEM:
const key = KEYUTIL.getKey(pemString);
Загрузка с паролем:
const key = KEYUTIL.getKey(pemEncrypted, "password");
Работа с JWK:
const key = KEYUTIL.getKey(jwkObject);
Особенность: библиотека автоматически определяет формат ключа, что
упрощает интеграцию, но увеличивает требования к валидации входных
данных.
Шифрование приватных ключей
Хранение приватного ключа в незашифрованном виде — критическая
уязвимость.
Jsrsasign поддерживает экспорт зашифрованных ключей:
const pemEncrypted = KEYUTIL.getPEM(privateKey, "PKCS8PRV", "password");
Под капотом используются алгоритмы:
- AES
- Triple DES
- PBKDF2 для генерации ключа из пароля
Ключевые параметры безопасности:
- длина соли
- количество итераций PBKDF2
- используемый симметричный алгоритм
Безопасное хранение в
браузере
В клиентских приложениях ключи особенно уязвимы.
Недопустимые подходы:
- хранение в
localStorage
- хранение в
sessionStorage
- встраивание в исходный код
Допустимые практики:
Web Crypto API + IndexedDB
- ключи генерируются внутри браузера
- приватный ключ не покидает защищённый контекст
Memory-only хранение
- ключ существует только в оперативной памяти
- удаляется при перезагрузке страницы
Использование аппаратных средств
- WebAuthn
- токены безопасности
Безопасное хранение на
сервере
На стороне сервера применяются другие стратегии:
Файловая система:
- доступ только для системного пользователя
- права:
600
- изоляция в контейнерах
HSM (Hardware Security Module):
- ключи не покидают устройство
- операции выполняются внутри модуля
KMS (Key Management Service):
- централизованное управление ключами
- автоматическая ротация
Ротация ключей
Регулярная смена ключей снижает риск компрометации.
Подходы:
- версия ключа (
kid в JWK)
- поддержка нескольких активных ключей
- плавная замена без остановки системы
Пример структуры:
{
"keys": [
{ "kid": "key1", ... },
{ "kid": "key2", ... }
]
}
Контроль доступа
Ключи должны использоваться строго в рамках минимально необходимых
прав.
Принципы:
- least privilege
- разделение ролей
- аудит операций
Практика:
- разные ключи для подписи и шифрования
- ограничение IP или сервисов
- журналирование использования
Защита от утечек
Основные источники утечек:
Логи
- случайный вывод ключа в консоль
- логирование PEM-строк
Снимки памяти
Сетевой трафик
- передача без TLS
- MITM-атаки
Меры защиты:
- маскирование данных
- отключение debug-режимов
- обязательный HTTPS
Очистка ключей из памяти
После использования ключи должны удаляться:
key = null;
Дополнительно:
- перезапись буферов
- минимизация времени жизни объекта
В JavaScript это ограничено сборщиком мусора, поэтому важно:
- не сохранять ссылки
- избегать глобальных переменных
Проверка целостности ключей
Перед использованием ключ необходимо валидировать:
KEYUTIL.getKey(pem);
Ошибки парсинга:
- повреждение структуры
- подмена данных
- некорректный формат
Дополнительно:
- проверка длины ключа
- проверка алгоритма
Использование паролей и
секретов
Пароль для шифрования ключа должен соответствовать требованиям:
- длина не менее 12 символов
- случайность
- отсутствие повторного использования
Рекомендуется:
- генерация через криптографический RNG
- хранение в менеджерах секретов
Интеграция с системами
секретов
Современные архитектуры используют:
- HashiCorp Vault
- AWS Secrets Manager
- Azure Key Vault
Преимущества:
- централизованное хранение
- контроль доступа
- аудит
Защита от атак на стороне
клиента
В браузере ключи подвержены:
- XSS-атакам
- внедрению скриптов
- расширениям браузера
Меры:
- CSP (Content Security Policy)
- sandbox iframe
- минимизация сторонних библиотек
Практика
безопасного использования Jsrsasign
Рекомендации:
- не хранить приватные ключи в коде
- использовать зашифрованные PEM
- ограничивать область видимости ключей
- регулярно обновлять зависимости
- проводить аудит кода
Антипаттерны:
const privateKey = "-----BEGIN PRIVATE KEY-----...";
localStorage.setItem("key", pem);
Разделение ключей по
назначению
Необходимо использовать разные ключи для:
- подписи (JWT, JWS)
- шифрования (JWE)
- TLS
Это снижает риск компрометации всей системы при утечке одного
ключа.
Метаданные ключей
При работе с JWK важно учитывать поля:
kid — идентификатор
alg — алгоритм
use — назначение
Пример:
{
"kty": "RSA",
"kid": "signing-key",
"use": "sig",
"alg": "RS256"
}
Обновление и отзыв ключей
При компрометации:
- Немедленный отзыв
- Удаление из доверенных
- Генерация нового ключа
- Уведомление зависимых систем
Логирование и аудит
Фиксируются:
- операции подписи
- ошибки
- попытки доступа
Не фиксируются:
Итерации PBKDF2 и защита
паролей
При шифровании ключей:
- минимум 10000 итераций
- лучше 100000+
- использование соли
Это усложняет перебор пароля.
Минимизация поверхности
атаки
- удаление неиспользуемых ключей
- ограничение API
- сегментация системы
Управление жизненным циклом
ключей
Этапы:
- Генерация
- Распространение
- Использование
- Ротация
- Удаление
Каждый этап требует контроля и логирования.
Совместимость и миграции
При смене формата:
- поддержка старых ключей
- конвертация через KEYUTIL
- тестирование на совместимость
Проверка алгоритмов
Недопустимо использование устаревших алгоритмов:
- MD5
- SHA1
- слабые RSA (менее 2048 бит)
Рекомендуется:
- RSA 2048+
- ECDSA
- SHA-256 и выше