# How to create a PEM file for storing an RSA key?

I have an RSA private key $\{d,n\}$ and a public key $\{e,n\}$, where $n$ is the modulus, and I also have the prime factors $p$ and $q$ of $n$.

I want to create a PEM file containing this information, so that I can decrypt a file encrypted with the public key using OpenSSL. How can I do this?

• I'm voting to close this question as off-topic because this is a question about how to use a particular software program (OpenSSL), not cryptography May 8, 2015 at 12:15
• @poncho: Technically, this question is about implementing a standard storage format for cryptographic keys. The mention of OpenSSL is really a red herring. I think it's on topic here, if perhaps marginally. (And there's certainly some overlap with Stack Overflow here; not that there's necessarily anything wrong with that.) May 9, 2015 at 11:44

RFC 2313 specifies the RSAPrivateKey ASN1 structure as a SEQUENCE containing the INTEGERs

• $$0$$;
• $$n$$;
• $$e$$;
• $$d$$;
• $$p$$;
• $$q$$;
• $$d\bmod(p-1)$$;
• $$d\bmod(q-1)$$;
• $$q^{-1}\bmod p$$.

The PEM format consists of such a structure encoded as Base64 and framed by the typical BEGIN/END RSA PRIVATE KEY header and footer lines.

Thus, you can use any ASN1 library you like to encode the private key parameters. For example, with Python's pyasn1 module, a private key file's contents can be obtained as follows:

import pyasn1.codec.der.encoder
import pyasn1.type.univ
import base64

def pempriv(n, e, d, p, q, dP, dQ, qInv):
template = '-----BEGIN RSA PRIVATE KEY-----\n{}-----END RSA PRIVATE KEY-----\n'
seq = pyasn1.type.univ.Sequence()
for i,x in enumerate((0, n, e, d, p, q, dP, dQ, qInv)):
seq.setComponentByPosition(i, pyasn1.type.univ.Integer(x))
der = pyasn1.codec.der.encoder.encode(seq)
return template.format(base64.encodebytes(der).decode('ascii'))


The parameters dP, dQ and qInv are most easily (as in: lines of code) computed as follows:

dP = d % (p-1)
dQ = d % (q-1)
qInv = pow(q, p-2, p)

• PyAsn1Error: Attempted "__len__" operation on ASN.1 schema object Jun 6, 2020 at 17:30
• @evandrix Thanks, seems like some internals of pyasn1 changed. Fixed. Jun 6, 2020 at 18:58
• python3 says: DeprecationWarning: encodestring() is a deprecated alias since 3.1, use encodebytes(). replacing it works fine as far as I can see. Mar 5, 2021 at 20:57
• the code given for dP and dQ is wrong. the one given for qInv is convoluted. consider this instead expected_dP = d % (p - 1);expected_dQ = d % (q - 1); expected_qInv = pow(q, -1, p) Mar 5, 2021 at 22:06
• @acapola Thanks! Fixed. Mar 6, 2021 at 18:49