KEYUTIL.getKey старого формата к современным методам
работы с ключамиВ ранних версиях Jsrsasign для работы с криптографическими ключами активно использовался универсальный метод:
var key = KEYUTIL.getKey(pem);
Он принимал строку PEM и автоматически пытался определить тип ключа (RSA, EC, DSA). Однако со временем подход стал считаться слишком неявным: при сложных сценариях парсинга или работе с нестандартными ключами возникали неоднозначности.
Современный подход предполагает явное указание типа ключа или использование специализированных функций:
var rsaKey = KEYUTIL.getKey(pem, null, "RSAKEY");
var ecKey = KEYUTIL.getKey(pem, null, "EC");
Также рекомендуется использовать раздельные функции для повышения читаемости и предсказуемости поведения:
KEYUTIL.getRSAKeyFromPlainPrivatePKCS8PEMKEYUTIL.getECPublicKeyFromPEMKEYUTIL.getKeyInfoЭто позволяет избежать автоматического определения типа и снижает вероятность ошибок при обработке нестандартных PEM-структур.
KJUR.jws.JWS.parse без проверки подписиРанние реализации разбора JWT через:
var result = KJUR.jws.JWS.parse(token);
возвращали структуру токена без обязательной проверки подписи. Это часто приводило к ошибочному восприятию безопасности: разработчики считали, что декодирование эквивалентно валидации.
В актуальной версии библиотеки предпочтительным является разделение операций:
var isValid = KJUR.jws.JWS.verifyJWT(token, key, { alg: ["RS256"] });
и только после этого:
var payloadObj = KJUR.jws.JWS.parse(token).payloadObj;
Либо использование:
KJUR.jws.JWS.verify(token, key, { alg: ["RS256"] });
с последующим разбором payload через b64utoutf8.
Основная причина отказа от старого подхода — предотвращение сценариев, при которых декодированный JWT воспринимается как доверенный.
KJUR.jws.IntDate.get и устаревшие преобразования
времениРанее для работы с UNIX-временем в JWT использовались методы:
KJUR.jws.IntDate.get("now");
KJUR.jws.IntDate.get("now + 3600");
Такой строковый парсинг времени был удобен, но приводил к скрытым ошибкам в сложных вычислениях.
Современный подход исключает строковые выражения:
var now = Math.floor(Date.now() / 1000);
var exp = now + 3600;
При необходимости форматирования используется явное преобразование:
var intDate = KJUR.jws.IntDate.getUnixTime(exp);
Функции с парсингом строк считаются устаревшими из-за низкой прозрачности вычислений.
KJUR.crypto.Signature.init в пользу явной конфигурации
алгоритмаСтарый способ инициализации подписи выглядел так:
var sig = new KJUR.crypto.Signature({ "alg": "SHA256withRSA" });
sig.init(privateKey);
В ранних версиях объект позволял гибко переключать алгоритмы уже после инициализации, что приводило к неоднозначному состоянию объекта.
Современный подход требует фиксировать алгоритм заранее:
var sig = new KJUR.crypto.Signature({ alg: "SHA256withRSA" });
sig.init(privateKey);
sig.updateString(data);
var signature = sig.sign();
Изменение алгоритма после создания объекта больше не поддерживается как безопасная практика.
KJUR.asn1.ASN1Util.newObject на специализированные
классыРанее:
var obj = KJUR.asn1.ASN1Util.newObject({
seq: [
{ int: 3 },
{ octstr: "abcd" }
]
});
Такой универсальный конструктор позволял описывать ASN.1 через JSON-подобную структуру, но страдал от слабой типизации и высокой вероятности ошибок.
Современная модель предполагает использование конкретных классов:
var seq = new KJUR.asn1.DERSequence({
array: [
new KJUR.asn1.DERInteger({ int: 3 }),
new KJUR.asn1.DEROctetString({ str: "abcd" })
]
});
Переход к классовой модели улучшает читаемость и упрощает отладку ASN.1-структур.
KJUR.jws.JWS.verifyJWT с автоматическим выбором
ключаСтарый вариант:
KJUR.jws.JWS.verifyJWT(token, key);
допускал сценарии, в которых ключ подбирался без явного указания алгоритма, что создавало риск атак типа algorithm confusion.
Современный подход требует строгого указания допустимых алгоритмов:
KJUR.jws.JWS.verifyJWT(token, key, {
alg: ["RS256", "ES256"]
});
Также рекомендуется предварительная проверка заголовка:
var header = KJUR.jws.JWS.readSafeJSONString(b64utoutf8(token.split(".")[0]));
Это позволяет исключить несоответствие алгоритма до проверки подписи.
Ранее широко использовались:
hextob64(str);
b64tohex(str);
Эти функции не учитывали URL-safe variant Base64, что критично для JWT.
Современная замена:
KJUR.lang.String.prototype.b64u;
KJUR.lang.String.prototype.b64utohex;
или прямые утилиты:
hextob64u(str);
b64utohex(str);
Использование URL-safe Base64 стало стандартом, поэтому старые методы считаются устаревшими в контексте JWS/JWT.
KJUR.crypto,
KJUR.jws без модульной изоляцииРанее Jsrsasign активно использовал глобальный объект
KJUR, что приводило к конфликтам в браузерных окружениях и
при сборке через bundler’ы:
KJUR.crypto.Signature
KJUR.jws.JWS
Современная практика предполагает импорт через модули:
import { KEYUTIL, KJUR } from "jsrsasign";
или использование ESM-сборок библиотеки.
Это позволяет избежать загрязнения глобального пространства и улучшает совместимость с Webpack, Vite и Node.js ESM.
KJUR.crypto.Mac старой инициализации на явное указание
алгоритмаРанее:
var mac = new KJUR.crypto.Mac({ alg: "HmacSHA256" });
mac.init(secret);
Позволялось менять алгоритм динамически, что приводило к неожиданным результатам при повторном использовании объекта.
Современный вариант фиксирует алгоритм при создании:
var mac = new KJUR.crypto.Mac({ alg: "HmacSHA256" });
mac.updateString(message);
var hmac = mac.doFinal();
Повторная инициализация с другим алгоритмом требует создания нового объекта.
KJUR.jws.JWS.parse для не-JWT токеновРанее метод применялся для разбора любых JWS-подобных структур:
KJUR.jws.JWS.parse(compactJWS);
Однако отсутствие строгой проверки структуры приводило к ошибкам при обработке некорректных токенов.
Современная практика:
KJUR.jws.JWS.isSafeJSONString(headerSegment)
KJUR.jws.JWS.verify(token, key)
Парсинг и валидация разделены на отдельные шаги, что снижает вероятность обработки повреждённых или поддельных токенов.
JWS.signРанее:
var jws = KJUR.jws.JWS.sign(null, header, payload, key);
Алгоритм мог быть определён из header, что создавало риск подмены
alg.
Современный подход:
var jws = KJUR.jws.JWS.sign("RS256", header, payload, key);
Явное указание алгоритма стало обязательной практикой, исключающей зависимость от входных данных заголовка.