Differences between "BEGIN RSA PRIVATE KEY" and "BEGIN PRIVATE KEY"

203,181

Solution 1

See https://polarssl.org/kb/cryptography/asn1-key-structures-in-der-and-pem (search the page for "BEGIN RSA PRIVATE KEY") (archive link for posterity, just in case).

BEGIN RSA PRIVATE KEY is PKCS#1 and is just an RSA key. It is essentially just the key object from PKCS#8, but without the version or algorithm identifier in front. BEGIN PRIVATE KEY is PKCS#8 and indicates that the key type is included in the key data itself. From the link:

The unencrypted PKCS#8 encoded data starts and ends with the tags:

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

Within the base64 encoded data the following DER structure is present:

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

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

So for an RSA private key, the OID is 1.2.840.113549.1.1.1 and there is a RSAPrivateKey as the PrivateKey key data bitstring.

As opposed to BEGIN RSA PRIVATE KEY, which always specifies an RSA key and therefore doesn't include a key type OID. BEGIN RSA PRIVATE KEY is PKCS#1:

RSA Private Key file (PKCS#1)

The RSA private key PEM file is specific for RSA keys.

It starts and ends with the tags:

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

Within the base64 encoded data the following DER structure is present:

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
}

Solution 2

Have a look at <openssl/pem.h>. It gives possible BEGIN markers.

Copying the content from the above link for quick reference:

#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"
Share:
203,181

Related videos on Youtube

monim
Author by

monim

loves computer and everything about it and passionate for knowledge, hope always to learn more and more :)

Updated on August 19, 2022

Comments

  • monim
    monim over 1 year

    Hi I was writing a program that imports private keys from a .pem file and create a private key object to use it later.. the problem I have faced is that some pem files header begin with

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

    while others begin with

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

    through my search I knew that the first ones are PKCS#8 formatted but I couldn't know what format does the other one belongs to.

  • monim
    monim over 10 years
    so, is there any format that is used except those two, and if there is how can I determine it from the header?
  • Jason C
    Jason C over 10 years
    I'd imagine any of the private key tags given in sonic's answer are fair game.
  • ZZ Coder
    ZZ Coder over 9 years
    For RSA keys, PKCS#1 contains CRT parameters, PKCS#8 doesn't. You can confirm this by looking at sizes. PKCS#8 is smaller even with more headers added. If you care about performance, use PKCS#1. My test shows 3 times faster.
  • freegoods
    freegoods about 9 years
    @ZZCoder, could you please provide some details on how you generated the keys and tested the performance? openssl genpkey -algorithm RSA -out key.pem generates the PKCS#8 key that does include the CRT parameters.
  • Paul Tobias
    Paul Tobias over 5 years
    To generate a PKCS#1 key the openssl genrsa command can be used. Using openssl req to generate both the private key and the crt will end up with a PKCS#8 key. The genpkey manual states The use of the genpkey program is encouraged over the algorithm specific utilities because additional algorithm options and ENGINE provided algorithms can be used.. But some software (mysql) can use only PKCS#1 keys. Converting from PKCS#8 to PKCS#1 can be done with openssl rsa -in key.pem -out key.pem. Converting the other way can be done with openssl pkey -in key.pem -out key.pem.
  • Suraj
    Suraj over 5 years
    Does this mean PKCS#1 does not define a encrypted RSA private key ?