Различия между «BEGIN RSA PRIVATE KEY» и «BEGIN PRIVATE KEY»

152

Привет, я писал программу, которая импортирует закрытые ключи из .pemфайла и создает объект закрытого ключа, чтобы использовать его позже. Проблема, с которой я столкнулся, заключается в том, что pemзаголовок некоторых файлов начинается с

-----BEGIN PRIVATE KEY-----

в то время как другие начинаются с

-----BEGIN RSA PRIVATE KEY-----

в результате поиска я узнал, что первые PKCS#8отформатированы, но я не мог знать, к какому формату относится другой.

Моним
источник

Ответы:

184

См. Https://polarssl.org/kb/cryptography/asn1-key-structures-in-der-and-pem (поищите на странице «BEGIN RSA PRIVATE KEY») ( архивная ссылка для потомков, на всякий случай).

BEGIN RSA PRIVATE KEYэто PKCS # 1 и является просто ключом RSA. По сути, это просто ключевой объект из PKCS # 8, но без идентификатора версии или алгоритма. BEGIN PRIVATE KEYявляется PKCS # 8 и указывает, что тип ключа включен в сами данные ключа. По ссылке:

Незашифрованные данные в формате PKCS # 8 начинаются и заканчиваются тегами:

-----BEGIN PRIVATE KEY-----
BASE64 ENCODED DATA
-----END PRIVATE KEY-----

В закодированных в base64 данных присутствует следующая структура DER:

PrivateKeyInfo ::= SEQUENCE {
  version         Version,
  algorithm       AlgorithmIdentifier,
  PrivateKey      BIT STRING
}

AlgorithmIdentifier ::= SEQUENCE {
  algorithm       OBJECT IDENTIFIER,
  parameters      ANY DEFINED BY algorithm OPTIONAL
}

Таким образом, для закрытого ключа RSA OID равен 1.2.840.113549.1.1.1, и в качестве цепочки данных ключа PrivateKey имеется RSAPrivateKey.

В отличие от BEGIN RSA PRIVATE KEY, который всегда указывает ключ RSA и, следовательно, не включает OID типа ключа. BEGIN RSA PRIVATE KEYэто PKCS#1:

Файл закрытого ключа RSA (PKCS # 1)

Файл PEM закрытого ключа RSA специфичен для ключей RSA.

Он начинается и заканчивается тегами:

-----BEGIN RSA PRIVATE KEY-----
BASE64 ENCODED DATA
-----END RSA PRIVATE KEY-----

В закодированных в base64 данных присутствует следующая структура DER:

RSAPrivateKey ::= SEQUENCE {
  version           Version,
  modulus           INTEGER,  -- n
  publicExponent    INTEGER,  -- e
  privateExponent   INTEGER,  -- d
  prime1            INTEGER,  -- p
  prime2            INTEGER,  -- q
  exponent1         INTEGER,  -- d mod (p-1)
  exponent2         INTEGER,  -- d mod (q-1)
  coefficient       INTEGER,  -- (inverse of q) mod p
  otherPrimeInfos   OtherPrimeInfos OPTIONAL
}
Джейсон С
источник
Итак, существует ли какой-либо формат, кроме этих двух, и если есть, как я могу определить его из заголовка?
Пн
1
Я полагаю, что любые теги закрытого ключа, приведенные в ответе Соника, являются честной игрой.
Джейсон С
Для ключей RSA PKCS # 1 содержит параметры CRT, PKCS # 8 - нет. Вы можете подтвердить это, посмотрев на размеры. PKCS # 8 меньше даже с добавлением большего количества заголовков. Если вы заботитесь о производительности, используйте PKCS # 1. Мой тест показывает в 3 раза быстрее.
ZZ Coder
5
@ZZCoder, не могли бы вы рассказать подробнее о том, как вы сгенерировали ключи и проверили производительность? openssl genpkey -algorithm RSA -out key.pemгенерирует ключ PKCS # 8, который включает параметры CRT.
Вадим Кузнецов
5
Для генерации ключа PKCS # 1openssl genrsa можно использовать команду. Использование openssl reqдля генерации как закрытого ключа, так и crt приведет к получению ключа PKCS # 8 . В genpkeyруководстве говорится The use of the genpkey program is encouraged over the algorithm specific utilities because additional algorithm options and ENGINE provided algorithms can be used.. Но некоторые программы ( mysql) могут использовать только ключи PKCS # 1 . Преобразование из PKCS # 8 в PKCS # 1 может быть сделано с openssl rsa -in key.pem -out key.pem. Преобразование другим способом может быть сделано с openssl pkey -in key.pem -out key.pem.
Пол Тобиас
28

Посмотрите на <openssl/pem.h>. Это дает возможные маркеры BEGIN.

Копирование содержимого по вышеуказанной ссылке для быстрого ознакомления:

#define PEM_STRING_X509_OLD "X509 CERTIFICATE"
#define PEM_STRING_X509     "CERTIFICATE"
#define PEM_STRING_X509_PAIR    "CERTIFICATE PAIR"
#define PEM_STRING_X509_TRUSTED "TRUSTED CERTIFICATE"
#define PEM_STRING_X509_REQ_OLD "NEW CERTIFICATE REQUEST"
#define PEM_STRING_X509_REQ "CERTIFICATE REQUEST"
#define PEM_STRING_X509_CRL "X509 CRL"
#define PEM_STRING_EVP_PKEY "ANY PRIVATE KEY"
#define PEM_STRING_PUBLIC   "PUBLIC KEY"
#define PEM_STRING_RSA      "RSA PRIVATE KEY"
#define PEM_STRING_RSA_PUBLIC   "RSA PUBLIC KEY"
#define PEM_STRING_DSA      "DSA PRIVATE KEY"
#define PEM_STRING_DSA_PUBLIC   "DSA PUBLIC KEY"
#define PEM_STRING_PKCS7    "PKCS7"
#define PEM_STRING_PKCS7_SIGNED "PKCS #7 SIGNED DATA"
#define PEM_STRING_PKCS8    "ENCRYPTED PRIVATE KEY"
#define PEM_STRING_PKCS8INF "PRIVATE KEY"
#define PEM_STRING_DHPARAMS "DH PARAMETERS"
#define PEM_STRING_DHXPARAMS    "X9.42 DH PARAMETERS"
#define PEM_STRING_SSL_SESSION  "SSL SESSION PARAMETERS"
#define PEM_STRING_DSAPARAMS    "DSA PARAMETERS"
#define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY"
#define PEM_STRING_ECPARAMETERS "EC PARAMETERS"
#define PEM_STRING_ECPRIVATEKEY "EC PRIVATE KEY"
#define PEM_STRING_PARAMETERS   "PARAMETERS"
#define PEM_STRING_CMS      "CMS"
Вишну Вишванат
источник