1
$\begingroup$

If I run cat my.key, I get:

-----BEGIN RSA PRIVATE KEY-----
MIIJKQIBAAKCAgEAu+UkIRXNZrdcnuCLsBsz/HiBcYNoAAAhYi2hISKBxkqX165U...

but if I run openssl rsa -in my.key, I get a different content as:

-----BEGIN PRIVATE KEY-----
MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQC75SQhFc1mt1ye...

why the contents are different, shouldn't they be the same?

$\endgroup$
1

1 Answer 1

2
$\begingroup$

The two base64 fragments in the question encode bytes which I show below in hex with spaces inserted to break things per ASN.1, and (for the first fragment corresponding to my.key) restore alignment with the second fragment.

                                                           30820929 020100 02820201 00BBE5242115CD66B75C9EE08BB01B33FC7881718368000021622DA1212281C64A97D7AE5454
30820943 020100 300D 0609 2A864886F70D010101 0500 0482092D 30820929 020100 02820201 00BBE5242115CD66B75C9E

We see that openssl rsa -in my.key has inserted a header of 26 bytes. As pointed by dave_thompson_085 in comment, this header is for a PrivateKeyInfo as defined in PKCS#8/RFC 5208. It's ASN.1 on the tune of:

SEQUENCE (0x0943=2371 bytes, 3 elements)
  INTEGER 0 // version
  SEQUENCE (0x0D=13 bytes, 2 elements) // privateKeyAlgorithm
    OBJECT IDENTIFIER (0x09=9 bytes) 1.2.840.113549.1.1.1 // rsaEncryption (PKCS #1)
    NULL // parameters
  OCTET STRING (0x092D=2349 bytes) // privateKey (header)

The big picture is that this PKCS#8 header tells what follows, so that programs can consistently recognize that the private key is for RSA rather than another algorithm.

In this

  • version is 0 (the first and AFAIK only PKCS#8 PrivateKeyInfo format)
  • the privateKeyAlgorithm is a PrivateKeyAlgorithmIdentifier, which itself is an AlgorithmIdentifier per PKCS#1v2.2 appendix C p.53, that is:
  • the privateKey in an OCTET STRING which bytes are the key itself, here an RSAPrivateKey SEQUENCE per PKCS#1v2.2 appendix C p.56, with 9 elements. This wrapping allows PKCS#8 to wrap keys uniformly, regardless of if they are defined as a SEQUENCE, another ASN.1 type, or structured per some other convention.
  • the optional attributes that could follow the key bytes is not present.

OpenSSL 3 by default uses PKCS#8 format to output keys, e.g.

openssl genrsa 4096
openssl req -nodes -newkey rsa:4096

Some OpenSSL tools have a flag to output the old format without PKCS#8 header, e.g.

openssl genrsa -traditional 4096

Note: the question disclosed the first bytes of the public modulus, but nothing confidential about the private key.

$\endgroup$
1
  • 1
    $\begingroup$ The difference is the RSA-specific structure defined by PKCS1 e.g. rfc8017 versus a PKCS8 structure defined in rfc5208. To avoid confusion, note openssl genrsa and openssl rsa (both) output PKCS1 in older OpenSSL (through 1.1.1), and many existing Stack posts use and depend on this, but they default to PKCS8 and require -traditional for PKCS1 in OpenSSL 3.0.0 up. OTOH req -newkey or genpkey or pkey have output PKCS8 since 1.0.0. $\endgroup$ Jun 21, 2023 at 0:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.