PKCS#1 определяет стандартную структуру RSA-ключей и криптографических операций: форматы представления ключей, математические параметры RSA, а также правила формирования и проверки цифровых подписей. В контексте JavaScript-библиотеки jsrsasign этот стандарт реализуется через набор объектов и утилит, позволяющих работать с PEM-ключами, выполнять подпись и верификацию, а также управлять параметрами алгоритмов.
RSA-ключ в PKCS#1 включает следующие основные компоненты:
n (modulus)edp и qdp, dq,
qiВ jsrsasign эти параметры инкапсулируются в объект RSAKey или создаются автоматически при разборе PEM-структуры.
RSA-ключи могут храниться в двух основных форматах:
PKCS#1 (RSA-specific) Содержит только RSA-параметры. Приватный ключ начинается с:
-----BEGIN RSA PRIVATE KEY-----
PKCS#8 (generic private key container) Универсальный формат для любых алгоритмов:
-----BEGIN PRIVATE KEY-----
jsrsasign поддерживает оба варианта через единый интерфейс:
const key = KEYUTIL.getKey(pem);
Функция автоматически определяет тип структуры и преобразует её в объект внутреннего представления RSAKey.
Внутреннее представление RSA-ключа в jsrsasign основано на объекте
RSAKey:
const rsaKey = KEYUTIL.getKey(pem);
После парсинга становятся доступны параметры:
rsaKey.n — модульrsaKey.e — публичная экспонентаrsaKey.d — приватная экспонента (если ключ
закрытый)rsaKey.isPrivate — признак приватного ключаПубличный ключ также может быть извлечён из приватного:
const pubKey = KEYUTIL.getPEM(rsaKey, "PKCS8PUB");
jsrsasign предоставляет встроенный механизм генерации ключевых пар:
const kp = KEYUTIL.generateKeypair("RSA", 2048);
const pub = KEYUTIL.getPEM(kp.pubKeyObj);
const prv = KEYUTIL.getPEM(kp.prvKeyObj, "PKCS1PRV");
Параметры генерации:
"RSA"Сгенерированный приватный ключ PKCS#1 может быть использован напрямую в криптографических операциях без дополнительной конвертации.
Основной класс для работы с подписями —
KJUR.crypto.Signature.
Процесс подписи включает три этапа:
const sig = new KJUR.crypto.Signature({ alg: "SHA256withRSA" });
sig.init(privateKeyPem);
sig.updateString("message");
const signature = sig.sign();
Алгоритм SHA256withRSA включает:
Верификация выполняется с использованием публичного ключа:
const sig = new KJUR.crypto.Signature({ alg: "SHA256withRSA" });
sig.init(publicKeyPem);
sig.updateString("message");
const isValid = sig.verify(signature);
Проверка включает:
jsrsasign поддерживает комбинации RSA с различными хеш-функциями:
Каждый алгоритм определяет длину хеша, влияющую на безопасность и размер подписи.
Пример выбора:
const sig = new KJUR.crypto.Signature({ alg: "SHA512withRSA" });
Помимо PKCS#1 v1.5 jsrsasign поддерживает RSA-PSS — более современную схему подписи.
const sig = new KJUR.crypto.Signature({
alg: "SHA256withRSAandMGF1",
prvkeypem: privateKeyPem
});
Особенности RSA-PSS:
PEM-кодирование представляет ключи в base64 с заголовками:
-----BEGIN RSA PRIVATE KEY-----
(base64)
-----END RSA PRIVATE KEY-----
jsrsasign автоматически:
Обратная операция:
const pem = KEYUTIL.getPEM(rsaKey);
Из приватного PKCS#1 ключа можно получить публичный компонент:
const prvKey = KEYUTIL.getKey(privatePem);
const pubPem = KEYUTIL.getPEM(prvKey, "PKCS8PUB");
Это используется в сценариях, где приватный ключ хранится централизованно, а публичный распространяется отдельно.
Некорректные сценарии обычно связаны с:
1. Несоответствие формата ключа
2. Неверный алгоритм подписи
3. Повреждение PEM
4. Несовпадение кодировки данных
PKCS#1 v1.5 остаётся широко используемым, однако имеет известные теоретические уязвимости в некоторых протоколах при неправильной реализации. В jsrsasign корректная реализация зависит от:
RSA-PSS снижает риски за счёт вероятностного заполнения и более строгой математической модели подписи.
jsrsasign способен работать с ключами, импортированными из OpenSSL:
openssl genrsa -out key.pem 2048
openssl rsa -in key.pem -pubout
Полученные PEM можно напрямую передавать в:
KEYUTIL.getKey()KJUR.crypto.Signature.init()Без дополнительных преобразований структура сохраняется в соответствии с PKCS#1 или PKCS#8 в зависимости от экспорта.