В библиотеке Jsrsasign работа с криптографическими ключами строится
вокруг утилиты KEYUTIL, которая обеспечивает
унифицированное преобразование различных представлений ключей в
внутренние структуры, используемые при подписи, проверке и шифровании.
Одним из наиболее важных сценариев является получение криптографического
ключа из JWK (JSON Web Key) — формата, стандартизированного в RFC 7517 и
широко применяемого в современных системах аутентификации и обмена
ключами.
JWK представляет ключ в виде JSON-структуры, содержащей параметры
алгоритма, тип ключа, кривую (для EC), модуль и экспоненту (для RSA), а
также дополнительные метаданные. Основная задача
KEYUTIL.getKey заключается в преобразовании этого
JSON-представления в объект ключа, который может быть использован внутри
Jsrsasign для криптографических операций.
JWK для RSA-ключа обычно содержит следующие поля:
kty — тип ключа (RSA, EC,
oct)n — модуль (base64url)e — экспонентаalg — рекомендуемый алгоритмkid — идентификатор ключаuse — назначение (sig,
enc)Пример JWK:
const jwk = {
kty: "RSA",
n: "0vx7agoebGcQSuuPiLJXZptN3h...",
e: "AQAB",
alg: "RS256",
kid: "2011-04-29"
};
В случае EC-ключей структура включает:
crv — кривая (например, P-256)x, y — координаты точкиd — приватный компонент (если ключ приватный)Основная функция преобразования:
const key = KEYUTIL.getKey(jwk);
Функция анализирует поле kty и определяет тип ключа,
после чего выполняет декодирование параметров из base64url и формирует
внутренний объект ключа Jsrsasign.
При обработке RSA-ключа происходит:
n (модуль) в BigIntegere (экспонента)Внутренне это эквивалентно созданию объекта:
const rsaKey = new RSAKey();
rsaKey.setPublic(n, e);
Однако KEYUTIL.getKey выполняет этот процесс
автоматически и поддерживает дополнительные проверки корректности
структуры JWK.
Для эллиптических кривых:
const ecKey = KEYUTIL.getKey(jwk);
Процесс включает:
crvx, yd — формирование приватного ключаJsrsasign использует внутреннюю реализацию ECDSA-ключей, совместимую с OpenSSL-форматами.
Если JWK содержит параметр d, ключ интерпретируется как
приватный. Это критически важно, так как наличие приватной части
открывает возможность выполнения операций подписи:
const privJwk = {
kty: "RSA",
n: "...",
e: "AQAB",
d: "KJd9..."
};
const key = KEYUTIL.getKey(privJwk);
После преобразования объект может использоваться в:
KJUR.crypto.SignatureKJUR.crypto.DecryptKEYUTIL.getKey сопоставляет JWK с криптографическими
алгоритмами Jsrsasign:
| kty | alg | Внутренний тип |
|---|---|---|
| RSA | RS256 / PS256 | RSAKey |
| EC | ES256 / ES384 | KJUR.crypto.ECDSA |
| oct | HS256 | Array/WordArray |
При отсутствии явного alg используется либо контекст
вызова, либо дефолтные правила библиотеки.
const jwk = {
kty: "RSA",
n: "...",
e: "AQAB",
d: "..."
};
const key = KEYUTIL.getKey(jwk);
const sig = new KJUR.crypto.Signature({ alg: "SHA256withRSA" });
sig.init(key);
sig.updateString("data");
const signature = sig.sign();
JWK использует base64url без padding. KEYUTIL.getKey
автоматически:
- на +_ на /Это позволяет корректно восстанавливать числовые значения RSA и EC параметров без ручной обработки.
Для симметричных ключей:
const jwk = {
kty: "oct",
k: "AyM1..."
};
В этом случае KEYUTIL.getKey возвращает бинарное
представление ключа, пригодное для HMAC-операций:
const key = KEYUTIL.getKey(jwk);
const sig = new KJUR.crypto.Signature({ alg: "HmacSHA256" });
sig.init(key);
При работе с KEYUTIL.getKey возникают типовые
ограничения:
n, e,
crv, k)kty структуре данныхВ таких случаях функция генерирует исключения, прерывающие процесс конвертации.
Логика преобразования включает несколько этапов:
ktyОсобое значение имеет этап нормализации: библиотека приводит разные JWK-диалекты к единому внутреннему представлению.
KEYUTIL.getKey поддерживает JWK, сгенерированные:
При этом важно учитывать различия:
ext, key_ops)Часто JWK приходит в составе JWKS:
const jwks = {
keys: [ jwk1, jwk2 ]
};
Выбор ключа осуществляется вручную по kid:
const key = KEYUTIL.getKey(jwks.keys[0]);
В реальных сценариях kid используется для выбора нужного
ключа перед вызовом getKey.
Хотя основная задача — получение объекта ключа, результат можно преобразовать:
const key = KEYUTIL.getKey(jwk);
const pem = KEYUTIL.getPEM(key);
Это полезно при интеграции с системами, ожидающими PEM-формат.
Если JWK содержит только публичные параметры:
n, ex, yто результатом будет только публичный ключ. Попытки выполнения операций подписи приведут к ошибке отсутствия приватного компонента.
Jsrsasign использует:
RSAKey — для RSA операцийKJUR.crypto.ECDSA — для ECKEYUTIL.getKey выступает адаптером между JSON-описанием
и этими структурами.
Поле alg не является обязательным для JWK, но влияет
на:
При конфликте между alg и фактическим использованием
приоритет отдается явному параметру в криптографическом вызове.