Генерация ключей на конкретной кривой

Библиотека jsrsasign предоставляет инструменты для работы с криптографией, включая генерацию ключевых пар на эллиптических кривых (EC). Эллиптические кривые широко применяются благодаря высокой криптостойкости при относительно малом размере ключей.

В основе лежит математическая модель эллиптическая кривая, определяемая уравнением вида:

[ y^2 = x^3 + ax + b]

Каждая конкретная кривая задаётся параметрами (a, b, p, G, n, h), где:

  • p — модуль конечного поля
  • G — базовая точка (генератор)
  • n — порядок точки
  • h — кофактор

В jsrsasign используются стандартные кривые, такие как:

  • secp256r1 (P-256)
  • secp384r1 (P-384)
  • secp521r1 (P-521)

Класс KeyPair и генерация EC-ключей

Генерация ключевой пары осуществляется через API библиотеки. Основной механизм — функция KEYUTIL.generateKeypair.

Пример генерации ключей на кривой secp256r1:

var kp = KEYUTIL.generateKeypair("EC", "secp256r1");

var privateKey = kp.prvKeyObj;
var publicKey = kp.pubKeyObj;

Результат:

  • prvKeyObj — объект приватного ключа
  • pubKeyObj — объект публичного ключа

Выбор конкретной кривой

Выбор кривой влияет на:

  • уровень безопасности
  • производительность
  • размер ключей

Наиболее часто используются:

Кривая Битовая длина Уровень безопасности
secp256r1 256 ~128 бит
secp384r1 384 ~192 бит
secp521r1 521 ~256 бит

Пример генерации на более сильной кривой:

var kp = KEYUTIL.generateKeypair("EC", "secp384r1");

Внутреннее устройство ключей

Приватный ключ EC представляет собой случайное число:

[ d ]

Публичный ключ вычисляется как:

[ Q = d G]

Q = d G

Где:

  • d — приватный ключ
  • G — базовая точка
  • Q — публичный ключ

Представление ключей

После генерации ключи можно экспортировать в различные форматы.

PEM (приватный ключ)

var prvPEM = KEYUTIL.getPEM(privateKey, "PKCS8PRV");

PEM (публичный ключ)

var pubPEM = KEYUTIL.getPEM(publicKey);

Генерация ключей с явным контролем параметров

Хотя обычно используется стандартное имя кривой, возможно указание параметров более явно:

var ec = new KJUR.crypto.ECDSA({curve: "secp256r1"});
var keypair = ec.generateKeyPairHex();

var prvHex = keypair.ecprvhex;
var pubHex = keypair.ecpubhex;

Здесь:

  • ecprvhex — приватный ключ в hex
  • ecpubhex — публичный ключ в hex

Проверка корректности ключей

Публичный ключ должен лежать на выбранной кривой. Библиотека автоматически проверяет корректность при создании, но при работе с внешними ключами проверка важна:

var ec = new KJUR.crypto.ECDSA({curve: "secp256r1"});
ec.setPublicKeyHex(pubHex);

var isValid = ec.verifyPublicKey(pubHex);

Генерация ключей с использованием случайности

Качество генерации зависит от источника случайных чисел. В jsrsasign используется криптографически стойкий генератор случайных чисел.

Приватный ключ:

[ d = (1, n-1)]

d

Если генератор случайных чисел небезопасен, вся криптосистема становится уязвимой.


Практические аспекты выбора кривой

При выборе кривой учитываются:

Совместимость:

  • P-256 — наиболее широко поддерживается

Производительность:

  • меньшие кривые быстрее

Безопасность:

  • P-384 и P-521 обеспечивают больший запас прочности

Использование ключей после генерации

Сгенерированные ключи применяются для:

  • цифровой подписи (ECDSA)
  • обмена ключами (ECDH)
  • аутентификации

Пример подготовки ключа к подписи:

var sig = new KJUR.crypto.Signature({"alg": "SHA256withECDSA"});
sig.init(privateKey);

Ошибки при генерации ключей

Типичные проблемы:

Неверное имя кривой

KEYUTIL.generateKeypair("EC", "wrongCurve"); // ошибка

Использование устаревших кривых

  • secp192r1 — не рекомендуется

Недостаточная энтропия

  • особенно в старых браузерах или embedded-системах

Расширенные настройки

Можно работать напрямую с объектами ECDSA:

var ec = new KJUR.crypto.ECDSA({
    curve: "secp521r1",
    prov: "cryptojs/jsrsa"
});

Связь с другими стандартами

EC-ключи в jsrsasign соответствуют стандартам:

  • SEC1
  • PKCS#8
  • X.509

Это обеспечивает совместимость с:

  • OpenSSL
  • WebCrypto API
  • другими криптографическими библиотеками

Итеративная генерация и тестирование

При необходимости можно генерировать несколько ключей:

for (var i = 0; i < 10; i++) {
    var kp = KEYUTIL.generateKeypair("EC", "secp256r1");
    console.log(kp.prvKeyObj);
}

Хранение ключей

После генерации важно:

  • хранить приватный ключ в защищённом виде
  • использовать шифрование (например, PBES2)
  • ограничивать доступ

Пример шифрования PEM:

var encPEM = KEYUTIL.getPEM(privateKey, "PKCS8PRV", "password");

Производительность генерации

Скорость генерации зависит от:

  • выбранной кривой
  • среды выполнения (Node.js / браузер)
  • реализации RNG

Примерные характеристики:

  • secp256r1 — быстро
  • secp521r1 — значительно медленнее

Взаимодействие с шестнадцатеричным форматом

Работа с hex удобна для низкоуровневых операций:

console.log("Private:", prvHex);
console.log("Public:", pubHex);

Публичный ключ обычно кодируется как:

[ 04 || X || Y]

где 04 — признак не сжатого ключа.


Сжатые и несжатые ключи

EC-публичные ключи бывают:

  • несжатые (начинаются с 0x04)
  • сжатые (0x02 или 0x03)

В jsrsasign по умолчанию используется несжатый формат.


Контроль длины ключа

Каждая кривая строго задаёт длину ключа:

  • secp256r1 → 256 бит
  • secp384r1 → 384 бит

Попытка использовать ключ другой длины приведёт к ошибке или некорректной работе.


Итоговая схема генерации

  1. Выбор кривой
  2. Генерация случайного d
  3. Вычисление Q = d·G
  4. Формирование объектов ключей
  5. Экспорт в нужный формат

Такая схема лежит в основе всех операций генерации EC-ключей в jsrsasign.