Экспорт ключей: KEYUTIL.getPEM

Функция KEYUTIL.getPEM из библиотеки Jsrsasign предназначена для экспорта криптографических ключей и сертификатов в формат PEM (Privacy-Enhanced Mail). Этот формат является текстовым представлением бинарных данных, закодированных в Base64 и обрамлённых служебными заголовками.

PEM широко используется в TLS/SSL, PKI-инфраструктуре, JWT-подписях и других криптографических сценариях.


Общий синтаксис

KEYUTIL.getPEM(keyObj, formatType, passwd, encAlg, hexType)

Параметры:

  • keyObj — объект ключа (RSA, EC, DSA, X.509 и др.)
  • formatType — тип PEM-формата
  • passwd — пароль (используется при шифровании приватного ключа)
  • encAlg — алгоритм шифрования (например, "AES-256-CBC")
  • hexType — дополнительный параметр для некоторых типов ключей

Поддерживаемые типы объектов

Функция принимает следующие типы:

  • RSA ключи (RSAKey)
  • EC ключи (ECDSA)
  • DSA ключи
  • Сертификаты X.509 (X509)
  • Объекты ASN.1
  • PKCS#5 / PKCS#8 структуры

Основные форматы PEM

1. Публичный ключ (PKCS#8)

var pubKeyPEM = KEYUTIL.getPEM(pubKeyObj, "PKCS8PUB");

Результат:

-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----

Используется для распространения открытых ключей.


2. Приватный ключ (PKCS#1, RSA)

var prvKeyPEM = KEYUTIL.getPEM(prvKeyObj, "PKCS1PRV");

Формат:

-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----

Подходит для старых систем и OpenSSL.


3. Приватный ключ (PKCS#8, незашифрованный)

var pem = KEYUTIL.getPEM(prvKeyObj, "PKCS8PRV");

Формат:

-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----

Современный универсальный формат.


4. Приватный ключ (PKCS#8, зашифрованный)

var pem = KEYUTIL.getPEM(prvKeyObj, "PKCS8PRV", "password123", "AES-256-CBC");

Формат:

-----BEGIN ENCRYPTED PRIVATE KEY-----
...
-----END ENCRYPTED PRIVATE KEY-----

Особенности:

  • Требует пароль
  • Использует PBKDF2 для генерации ключа
  • Повышает безопасность хранения

5. Сертификат X.509

var certPEM = KEYUTIL.getPEM(x509Obj);

Формат:

-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----

Используется в HTTPS, TLS, цифровых подписях.


Пример полного цикла

Генерация ключа и экспорт

var keypair = KEYUTIL.generateKeypair("RSA", 2048);

var prvPEM = KEYUTIL.getPEM(keypair.prvKeyObj, "PKCS8PRV");
var pubPEM = KEYUTIL.getPEM(keypair.pubKeyObj, "PKCS8PUB");

Шифрование приватного ключа

var encryptedPEM = KEYUTIL.getPEM(
    keypair.prvKeyObj,
    "PKCS8PRV",
    "strongPassword",
    "AES-256-CBC"
);

Ключевые моменты:

  • Без пароля ключ хранится в открытом виде

  • С паролем — защищён от утечек

  • Алгоритмы шифрования:

    • AES-128-CBC
    • AES-192-CBC
    • AES-256-CBC
    • DES-EDE3-CBC

Отличия PKCS#1 и PKCS#8

Характеристика PKCS#1 PKCS#8
Поддержка ключей Только RSA Универсальный
Структура Простая ASN.1 обёртка
Шифрование Ограниченное Гибкое
Совместимость OpenSSL Современные системы

PKCS#8 рекомендуется для новых проектов.


Работа с EC-ключами

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

var pem = KEYUTIL.getPEM(ecKey.prvKeyObj, "PKCS8PRV");

Результат:

-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----

Для EC-ключей PKCS#8 — основной формат.


Экспорт публичного ключа из сертификата

var x509 = new X509();
x509.readCertPEM(certPEM);

var pubKeyObj = x509.getPublicKey();
var pubPEM = KEYUTIL.getPEM(pubKeyObj);

Работа с ASN.1 объектами

var pem = KEYUTIL.getPEM(asn1Obj, "CERTIFICATE");

Используется при ручной сборке криптографических структур.


Частые ошибки

1. Неверный formatType

KEYUTIL.getPEM(keyObj, "WRONG_FORMAT");

Результат — ошибка или некорректный PEM.


2. Отсутствие пароля при шифровании

KEYUTIL.getPEM(keyObj, "PKCS8PRV", null, "AES-256-CBC");

Шифрование не произойдёт.


3. Использование неподходящего объекта

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

KEYUTIL.getPEM("string", "PKCS8PRV");

Требуется объект (RSAKey, ECDSA, и т.д.)


Внутренний механизм

Функция выполняет несколько этапов:

  1. Преобразование ключа в ASN.1 структуру
  2. Кодирование DER (binary)
  3. Base64 кодирование
  4. Добавление PEM-заголовков
  5. При необходимости — шифрование

Пример структуры PEM

-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASC...
...
-----END PRIVATE KEY-----

Особенности:

  • Строки длиной 64 символа
  • Base64-кодировка
  • Чёткие границы BEGIN/END

Рекомендации по использованию

  • Использовать PKCS#8 для универсальности
  • Шифровать приватные ключи в production
  • Хранить ключи отдельно от кода
  • Проверять формат перед передачей в сторонние системы

Сценарии применения

  • Генерация ключей для JWT (RS256, ES256)
  • TLS/SSL конфигурации
  • Подпись данных
  • Верификация сертификатов
  • Интеграция с OpenSSL

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

PEM, сгенерированный через KEYUTIL.getPEM, полностью совместим с OpenSSL:

openssl rsa -in key.pem -text

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

  • Экспорт — операция средней сложности
  • Основная нагрузка — ASN.1 кодирование
  • Шифрование увеличивает время выполнения

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

  • Никогда не сохранять незашифрованные ключи в открытых репозиториях
  • Использовать сильные пароли
  • Ограничивать доступ к PEM-файлам
  • При возможности — использовать аппаратные хранилища (HSM)

Итоговая схема использования

  1. Генерация или загрузка ключа
  2. Преобразование в объект Jsrsasign
  3. Вызов KEYUTIL.getPEM
  4. Сохранение или передача PEM

Функция KEYUTIL.getPEM является ключевым инструментом для взаимодействия с внешними криптографическими системами и стандартами.