Differences between "BEGIN RSA PRIVATE KEY" and "BEGIN PRIVATE KEY"
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"
Related videos on Youtube
monim
loves computer and everything about it and passionate for knowledge, hope always to learn more and more :)
Updated on August 19, 2022Comments
-
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 somepem
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 over 10 yearsso, is there any format that is used except those two, and if there is how can I determine it from the header?
-
Jason C over 10 yearsI'd imagine any of the private key tags given in sonic's answer are fair game.
-
ZZ Coder over 9 yearsFor 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 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 over 5 yearsTo generate a PKCS#1 key the
openssl genrsa
command can be used. Usingopenssl req
to generate both the private key and the crt will end up with a PKCS#8 key. Thegenpkey
manual statesThe 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 withopenssl rsa -in key.pem -out key.pem
. Converting the other way can be done withopenssl pkey -in key.pem -out key.pem
. -
Suraj over 5 yearsDoes this mean PKCS#1 does not define a encrypted RSA private key ?