Diferenças entre "BEGIN RSA PRIVATE KEY" e "BEGIN PRIVATE KEY"

150

Olá, eu estava escrevendo um programa que importa chaves privadas de um .pemarquivo e cria um objeto de chave privada para usá-lo mais tarde .. o problema que enfrentei é que alguns pemcabeçalhos de arquivos começam com

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

enquanto outros começam com

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

através da minha pesquisa, sabia que os primeiros estavam PKCS#8formatados, mas não sabia a que formato pertence o outro.

monim
fonte

Respostas:

183

Consulte https://polarssl.org/kb/cryptography/asn1-key-structures-in-der-and-pem (pesquise na página "BEGIN RSA PRIVATE KEY") ( link do arquivo para posteridade, apenas no caso).

BEGIN RSA PRIVATE KEYé PKCS # 1 e é apenas uma chave RSA. É essencialmente apenas o objeto-chave do PKCS # 8, mas sem o identificador de versão ou algoritmo à frente. BEGIN PRIVATE KEYé PKCS # 8 e indica que o tipo de chave está incluído nos próprios dados da chave. No link:

Os dados codificados PKCS # 8 não criptografados começam e terminam com as tags:

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

Nos dados codificados em base64, a seguinte estrutura DER está presente:

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

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

Portanto, para uma chave privada RSA, o OID é 1.2.840.113549.1.1.1 e existe um RSAPrivateKey como a cadeia de bits de dados da chave PrivateKey.

Ao contrário de BEGIN RSA PRIVATE KEY, que sempre especifica uma chave RSA e, portanto, não inclui um tipo de chave OID. BEGIN RSA PRIVATE KEYé PKCS#1:

Arquivo de chave privada RSA (PKCS # 1)

O arquivo PEM de chave privada RSA é específico para chaves RSA.

Começa e termina com as tags:

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

Nos dados codificados em base64, a seguinte estrutura DER está presente:

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
}
Jason C
fonte
então, existe algum formato usado, exceto os dois, e se houver, como posso determiná-lo no cabeçalho?
monim
1
Eu imagino que qualquer uma das tags de chave privada dadas na resposta do Sonic seja justa.
Jason C
Para chaves RSA, o PKCS # 1 contém parâmetros CRT, o PKCS # 8 não. Você pode confirmar isso examinando os tamanhos. O PKCS # 8 é menor, mesmo com mais cabeçalhos adicionados. Se você se preocupa com o desempenho, use o PKCS # 1. Meu teste mostra 3 vezes mais rápido.
ZZ Coder
5
@ZZCoder, você poderia fornecer alguns detalhes sobre como você gerou as chaves e testou o desempenho? openssl genpkey -algorithm RSA -out key.pemgera a chave PKCS # 8 que inclui os parâmetros CRT.
Vadim Kuznetsov
5
Para gerar uma chave PKCS # 1, o openssl genrsacomando pode ser usado. Usar openssl reqpara gerar a chave privada e a crt terminará com uma chave PKCS # 8 . O genpkeymanual declara The use of the genpkey program is encouraged over the algorithm specific utilities because additional algorithm options and ENGINE provided algorithms can be used.. Mas alguns softwares ( mysql) podem usar apenas as teclas PKCS # 1 . A conversão de PKCS # 8 para PKCS # 1 pode ser feita com openssl rsa -in key.pem -out key.pem. A conversão para o outro lado pode ser feita com openssl pkey -in key.pem -out key.pem.
Paul Tobias
28

Dê uma olhada <openssl/pem.h>. Dá possíveis marcadores de COMEÇO.

Copiando o conteúdo do link acima para referência rápida:

#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"
vishnu viswanath
fonte