Общая роль
PKCS#5 в криптографической экосистеме
PKCS#5 описывает стандарт, определяющий методы защиты
криптографических ключей с использованием паролей. Основная задача этого
стандарта — безопасное преобразование пароля пользователя в
криптографический ключ, который затем используется для шифрования
приватных данных, включая закрытые ключи RSA и EC.
В контексте JavaScript-библиотеки Jsrsasign PKCS#5 используется
для:
- шифрования приватных ключей в формате PEM
- расшифровки защищённых ключей
- генерации ключей шифрования из паролей
- поддержки совместимости с OpenSSL и другими криптосистемами
Версии PKCS#5: PBKDF1 и
PBKDF2
PKCS#5 имеет две основные редакции алгоритмов вывода ключей из
пароля.
PKCS#5 v1 (PBKDF1)
Более старая схема, основанная на однократном хешировании:
- Использует MD5 или SHA-1
- Ограничена длиной выходного ключа
- Считается устаревшей
Формально процесс выглядит как итеративное хеширование:
- DK = HASH^c(password + salt)
Где:
- DK — derived key
- c — количество итераций
- salt — случайная добавка
PKCS#5 v2 (PBKDF2)
Современный стандарт, используемый в Jsrsasign по умолчанию.
DK = (P, S, c, dkLen)
Где:
- P — пароль
- S — salt
- c — число итераций
- dkLen — длина ключа
Особенности PBKDF2:
- поддержка HMAC-SHA1, SHA256 и других
- высокая устойчивость к brute-force атакам
- регулируемая сложность через итерации
- используется в OpenSSL, PKCS#12, JWT-системах
Формат защищённых приватных
ключей
В PKCS#5 защищённый приватный ключ обычно хранится в PEM-формате:
-----BEGIN ENCRYPTED PRIVATE KEY-----
...
-----END ENCRYPTED PRIVATE KEY-----
Внутри содержится:
- алгоритм шифрования (AES, DES-EDE3 и др.)
- параметры PBKDF2 (salt, iteration count)
- зашифрованный приватный ключ
Jsrsasign умеет автоматически определять эти параметры при
парсинге.
Шифрование приватного
ключа в Jsrsasign
В библиотеке Jsrsasign основной инструмент работы с ключами —
KEYUTIL.
Пример
генерации RSA ключа и его шифрования паролем
const { KEYUTIL, KJUR } = require("jsrsasign");
// генерация RSA ключа
const kp = KEYUTIL.generateKeypair("RSA", 2048);
// приватный ключ
const prv = kp.prvKeyObj;
// шифрование приватного ключа паролем
const encryptedPEM = KEYUTIL.getPEM(prv, "PKCS5PRV", "myStrongPassword");
console.log(encryptedPEM);
Здесь:
PKCS5PRV указывает использование PKCS#5 шифрования
- пароль применяется через PBKDF2 автоматически
- результат — зашифрованный PEM
Дешифрование приватного
ключа
Для восстановления ключа используется тот же пароль:
const { KEYUTIL } = require("jsrsasign");
const pem = `-----BEGIN ENCRYPTED PRIVATE KEY-----...`;
const prvKeyObj = KEYUTIL.getKey(pem, "myStrongPassword");
console.log(prvKeyObj);
Если пароль неверный, Jsrsasign выбрасывает исключение.
Внутренний механизм
PKCS#5 в Jsrsasign
При шифровании происходит несколько этапов:
1. Генерация salt
Случайная последовательность байтов:
- увеличивает стойкость к радужным таблицам
- хранится внутри PEM
2. Вывод ключа PBKDF2
Пароль + salt → криптографический ключ фиксированной длины.
3. Шифрование приватного ключа
Чаще всего используется:
- AES-128-CBC
- AES-256-CBC
- 3DES (устаревший вариант)
4.
Формирование структуры PKCS#8 EncryptedPrivateKeyInfo
Включает:
- алгоритм шифрования
- параметры PBKDF2
- зашифрованный блок ключа
Поддерживаемые алгоритмы в
Jsrsasign
Jsrsasign поддерживает набор алгоритмов, совместимых с PKCS#5:
- PBKDF2-HMAC-SHA1
- PBKDF2-HMAC-SHA256
- AES-CBC
- 3DES-EDE-CBC
Контроль параметров PBKDF2
При необходимости параметры можно задавать вручную через
низкоуровневые API:
const { KJUR } = require("jsrsasign");
const derivedKey = KJUR.crypto.PBKDF2.deriveKeyFromPassword(
"password",
"randomSalt",
10000,
32,
"SHA-256"
);
Параметры:
- 10000 — количество итераций
- 32 — длина ключа в байтах
- SHA-256 — HMAC функция
Совместимость с OpenSSL
Jsrsasign создаёт PKCS#5-совместимые структуры, которые можно
использовать в OpenSSL:
openssl rsa -in key.pem -out decrypted.pem
И наоборот — ключи OpenSSL могут быть прочитаны в Jsrsasign.
Типичные ошибки при работе с
PKCS#5
Неверный пароль
Частая причина ошибок:
- неправильная кодировка строки
- лишние пробелы
- несовпадение алгоритма
Несовместимый формат
Некоторые ключи используют:
- PKCS#1 вместо PKCS#8
- устаревшие DES-алгоритмы
Jsrsasign может требовать явного указания формата.
Слабые параметры PBKDF2
- маленькое число итераций снижает безопасность
- рекомендуется минимум 10000+
Практическая
схема использования в приложениях
PKCS#5 в Jsrsasign обычно применяется в следующих сценариях:
- хранение приватных ключей в браузере
- защищённый экспорт ключей
- клиентское шифрование перед отправкой на сервер
- локальные криптографические приложения
Формирование
безопасного ключевого контейнера
Типичная структура:
- Генерация RSA/EC ключа
- Выбор сильного пароля
- PBKDF2 с высокой итерацией
- AES-256-CBC шифрование
- Сохранение PEM
Работа с
несколькими алгоритмами шифрования
Jsrsasign позволяет гибко выбирать алгоритм:
KEYUTIL.getPEM(prvKey, "PKCS5PRV", password, "AES256");
Возможные значения:
- “AES128”
- “AES192”
- “AES256”
- “DES3”
Внутренние структуры
PKCS#5/PKCS#8
EncryptedPrivateKeyInfo включает:
- encryptionAlgorithm
- salt
- iterationCount
- encryptedData
Эта структура стандартизирована ASN.1, что обеспечивает
межплатформенную совместимость.
Повышение
криптографической стойкости
Рекомендации при использовании PKCS#5 в Jsrsasign:
- использовать PBKDF2 с SHA-256 или выше
- увеличивать число итераций при современных CPU
- избегать DES и MD5
- применять AES-256-CBC
Типовой цикл работы с
защищённым ключом
- Генерация ключа
- Шифрование PKCS#5
- Сохранение PEM
- Загрузка PEM
- Дешифрование через пароль
- Использование приватного ключа
Особенности реализации
Jsrsasign
- полностью JavaScript-реализация без нативных зависимостей
- совместимость с ASN.1 структурами OpenSSL
- поддержка как PKCS#5 v1, так и v2
- интеграция с RSA/EC ключами через KEYUTIL