Search code examples
opensslrsaprivate-keypem

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


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.


Solution

  • 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
    }