# Which elements of private RSA file are really constitutive of private key?

I have used openssl rsa to generate a RSA key of 2048 bits and as expected output belongs to a file beginning with BEGIN RSA PRIVATE KEY pattern. However this file size is ways larger than 2048 bits. In order to extract the key, i have used the following openssl command:

openssl rsa -in key.txt -text


which returns data for the following items:

• modulus
• publicExponent
• privateExponent (size is 2048 bits)
• prime1
• prime2
• exponent1
• exponent2

So which parts of this file are constitutive of the private key? Which are the only sufficient parts to be understood by a cryptographic system? Can I just strip all data except privateExponent and would it still be interpreted as private key?

EDIT

I seems that the couple (modulus, publicExponent) is the public key. However, as mentionned in your answer, puboicExponent is always 65537? Or have I misunderstood it?

It looks like all i need to perform private key operation is d=privateExponent. however, tools such as openssl would need a formated file with all informations, is there a simple way to make it understand that d (and n retrieved from certificate) is all i have and is sufficient for cryptographic operations ?

• Neardupe crypto.stackexchange.com/questions/31838/… . But if you're using certificates -- as many but not all PKC applications do -- they normally dwarf the space used for privatekey -- and so does the OpenSSL code which is pretty huge. – dave_thompson_085 Nov 7 '19 at 2:44
• See crypto.stackexchange.com/questions/45151/…. The private key file actually contains the private key (i.e. the two large primes), and the public key (i.e. the modulus and exponent). The above link shows where in the private key file the two large primes are stored. – mti2935 Mar 28 at 22:15

This is a harder question than that it looks.

To perform "plain" RSA modular exponentiation you can simply use the private exponent and the modulus. However, for faster RSA calculations that use the Chinese Remainder Theorem (CRT) you need the prime values, exponents and modulus. For RSA CRT you don't need the private exponent.

In principle you can calculate all private values from the primes: that's just RSA key pair generation after all: you find primes and then you perform calculations on them. So just storing the primes is a space efficient option. However, it does mean you have to recreate the modulus and private exponent or the CRT parameters before every RSA calculation, which will take time.

There is one even more space efficient option: store the random seed from which the prime search starts from, but it comes with a large set of problems (such as having to find the primes for each calculation, which is a terribly inefficient operation). However, it does mean you can store just 128 bits.

To get back the CRT parameters from just the private exponent and modulus is possible, but it takes time and thus negates any advantage to use CRT in the first place. So that kind of calculation should just be performed once, if at all. It can make sense if you first did choose plain RSA and then decide to go for CRT calculations. This is hard to do - tools will generally not include this option - so I would try and avoid having to ever use it.

The public exponent you don't need for private key operations. Sometimes the public key is used to verify that the operation concluded successfully (e.g. by verifying a signature right after generating it). This is of course a fully optional operation and usually only performed to make sure nobody messed with the generation in the first place.

You can say that the public exponent is mainly included because it may be easily / efficiently calculated / guessed from the private exponent, so including it makes sense for PKCS#1, where the structure in the question is defined.

Note that the public exponent is often simply set to a single small value, 65537 or F4, the fifth prime of Fermat. This is what OpenSSL (currently) uses by default.

EDIT: I don't think you can leave too much out if you're required to deal with OpenSSL. OpenSSL uses PKCS#1 or PKCS#8 private RSA keys. PKCS#8 simply includes the PKCS#1 private key, so that representation is just ever so slightly larger.

In turn, PKCS#1 is defined as follows (from the ASN.1 module in Appendix C of RFC 3447 that defines PKCS#1):

--
-- Representation of RSA private key with information for the CRT
-- algorithm.
--
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
}


as you can see, most of the stuff in there is non-optional. Only otherPrimeInfos can - and usually will already - be empty as it is used for CRT multi-prime computations.

• Many thanks for your answer. However, i still have questions : please have a look at my edits! – philippe Nov 6 '19 at 14:13
• @philippe Maarten says often for 65537. While generating with OpenSSL, all generated. You can delete some of you want. – kelalaka Nov 6 '19 at 14:22
• @kelalaka But I'm not sure what openssl will accept, as none of the fields are optional. – Maarten Bodewes Nov 6 '19 at 18:20
• AFAIR, in one of my projects, I've removed the CRT part to disable CRT based calculations. – kelalaka Nov 6 '19 at 19:54
• A reason to use the public key when signing is to verify the generated signature to prevent glitching attacks that could reveal private information. This is especially important when using CRT because a single bit flip (e.g. due to Rowhammer) at the wrong time reveals the key if the attacker can see a correct signature and a glitched signature of the same message. – Gilles 'SO- stop being evil' Nov 6 '19 at 21:35