Семейство алгоритмов ES256, ES384 и ES512 основано на схеме ECDSA (Elliptic Curve Digital Signature Algorithm) в сочетании с хэш-функциями SHA-2. Различия между ними определяются используемой длиной хэша и кривой эллиптической криптографии.
В библиотеке Jsrsasign данные алгоритмы применяются в контексте цифровых подписей и JSON Web Signature (JWS), а также при работе с криптографическими ключами в формате PEM.
ECDSA в Jsrsasign реализуется через модуль
KJUR.crypto.ECDSA и высокоуровневый интерфейс
KJUR.crypto.Signature.
Каждый алгоритм ES256/384/512 использует фиксированную связку:
Соответствие алгоритмов:
| Алгоритм | Кривая | Хэш | Длина ключа |
|---|---|---|---|
| ES256 | P-256 | SHA-256 | 256 бит |
| ES384 | P-384 | SHA-384 | 384 бита |
| ES512 | P-521 | SHA-512 | 521 бит |
Jsrsasign поддерживает генерацию ключевых пар через
KEYUTIL.
const kp = KEYUTIL.generateKeypair("EC", "secp256r1");
const privateKey = kp.prvKeyObj;
const publicKey = kp.pubKeyObj;
Для разных алгоритмов используются разные кривые:
// ES256
KEYUTIL.generateKeypair("EC", "secp256r1");
// ES384
KEYUTIL.generateKeypair("EC", "secp384r1");
// ES512
KEYUTIL.generateKeypair("EC", "secp521r1");
Экспорт в PEM формат:
const pemPrv = KEYUTIL.getPEM(privateKey, "PKCS8PRV");
const pemPub = KEYUTIL.getPEM(publicKey);
Низкоуровневое создание ECDSA-подписи осуществляется через объект
Signature.
const sig = new KJUR.crypto.Signature({ "alg": "SHA256withECDSA" });
sig.init(privateKey);
sig.updateString("data to sign");
const signatureHex = sig.sign();
const sig = new KJUR.crypto.Signature({ "alg": "SHA384withECDSA" });
sig.init(privateKey);
sig.updateString("data to sign");
const signatureHex = sig.sign();
const sig = new KJUR.crypto.Signature({ "alg": "SHA512withECDSA" });
sig.init(privateKey);
sig.updateString("data to sign");
const signatureHex = sig.sign();
Подпись возвращается в формате HEX DER, что является стандартным представлением ECDSA в Jsrsasign.
Проверка выполняется тем же объектом Signature, но с
публичным ключом.
const sig = new KJUR.crypto.Signature({ "alg": "SHA256withECDSA" });
sig.init(publicKey);
sig.updateString("data to sign");
const isValid = sig.verify(signatureHex);
Аналогично для ES384 и ES512 меняется только алгоритм SHA.
Наиболее распространённое применение — цифровые подписи JWT (JSON Web
Token). Jsrsasign предоставляет модуль KJUR.jws.JWS.
const header = { alg: "ES256", typ: "JWT" };
const payload = { sub: "1234567890", name: "Alice", admin: true };
const jwt = KJUR.jws.JWS.sign(
"ES256",
JSON.stringify(header),
JSON.stringify(payload),
privateKey
);
const jwt = KJUR.jws.JWS.sign(
"ES384",
JSON.stringify(header),
JSON.stringify(payload),
privateKey
);
const jwt = KJUR.jws.JWS.sign(
"ES512",
JSON.stringify(header),
JSON.stringify(payload),
privateKey
);
const result = KJUR.jws.JWS.verify(jwt, publicKey, ["ES256"]);
Для ES384 и ES512 список допустимых алгоритмов расширяется:
KJUR.jws.JWS.verify(jwt, publicKey, ["ES384"]);
KJUR.jws.JWS.verify(jwt, publicKey, ["ES512"]);
ECDSA подпись внутри JWS хранится не как DER HEX, а в формате R || S, закодированном через Base64URL.
Jsrsasign автоматически выполняет преобразование:
Это важно при интеграции с внешними системами, где формат ECDSA может отличаться.
JWS использует модифицированный Base64:
+ → -/ → _= paddingJsrsasign выполняет это преобразование автоматически при вызове
KJUR.jws.JWS.sign.
Несоответствие кривой и алгоритма приводит к ошибкам подписи.
Корректные пары:
Пример неправильной конфигурации:
KEYUTIL.generateKeypair("EC", "secp256r1"); // нельзя использовать с ES512
Jsrsasign поддерживает несколько форматов ключей:
Импорт PEM:
const prvKey = KEYUTIL.getKey(pemPrivateKey);
const pubKey = KEYUTIL.getKey(pemPublicKey);
ECDSA процесс внутри библиотеки включает:
Несовпадение алгоритма в заголовке JWS и подписи
alg: "ES256"
// но используется SHA384withECDSA
Использование неправильной кривой
ES512 + secp256r1 // некорректно
Передача ключа в неверном формате
init("string-key") // ожидается KeyObject
Jsrsasign совместим с:
При интеграции важно учитывать: