this is the first time I write here. I'm studying a library to encrypt/decrypt with RSA algorithm.

In an example given by the library I found this:

/* RSA 1024 Test Vector 1 */

const uint8_t T1_Modulus[] =

    0xa5, 0x6e, 0x4a, 0x0e, 0x70, 0x10, 0x17, 0x58, 0x9a, 0x51, 0x87, 0xdc, 0x7e, 0xa8, 0x41, 0xd1,
    0x56, 0xf2, 0xec, 0x0e, 0x36, 0xad, 0x52, 0xa4, 0x4d, 0xfe, 0xb1, 0xe6, 0x1f, 0x7a, 0xd9, 0x91,
    0xd8, 0xc5, 0x10, 0x56, 0xff, 0xed, 0xb1, 0x62, 0xb4, 0xc0, 0xf2, 0x83, 0xa1, 0x2a, 0x88, 0xa3,
    0x94, 0xdf, 0xf5, 0x26, 0xab, 0x72, 0x91, 0xcb, 0xb3, 0x07, 0xce, 0xab, 0xfc, 0xe0, 0xb1, 0xdf,
    0xd5, 0xcd, 0x95, 0x08, 0x09, 0x6d, 0x5b, 0x2b, 0x8b, 0x6d, 0xf5, 0xd6, 0x71, 0xef, 0x63, 0x77,
    0xc0, 0x92, 0x1c, 0xb2, 0x3c, 0x27, 0x0a, 0x70, 0xe2, 0x59, 0x8e, 0x6f, 0xf8, 0x9d, 0x19, 0xf1,
    0x05, 0xac, 0xc2, 0xd3, 0xf0, 0xcb, 0x35, 0xf2, 0x92, 0x80, 0xe1, 0x38, 0x6b, 0x6f, 0x64, 0xc4,
    0xef, 0x22, 0xe1, 0xe1, 0xf2, 0x0d, 0x0c, 0xe8, 0xcf, 0xfb, 0x22, 0x49, 0xbd, 0x9a, 0x21, 0x37,


const uint8_t T1_pubExp[] =
    0x01, 0x00, 0x01

const uint8_t T1_privExp[] =

    0x33, 0xa5, 0x04, 0x2a, 0x90, 0xb2, 0x7d, 0x4f, 0x54, 0x51, 0xca, 0x9b, 0xbb, 0xd0, 0xb4, 0x47,
    0x71, 0xa1, 0x01, 0xaf, 0x88, 0x43, 0x40, 0xae, 0xf9, 0x88, 0x5f, 0x2a, 0x4b, 0xbe, 0x92, 0xe8,
    0x94, 0xa7, 0x24, 0xac, 0x3c, 0x56, 0x8c, 0x8f, 0x97, 0x85, 0x3a, 0xd0, 0x7c, 0x02, 0x66, 0xc8,
    0xc6, 0xa3, 0xca, 0x09, 0x29, 0xf1, 0xe8, 0xf1, 0x12, 0x31, 0x88, 0x44, 0x29, 0xfc, 0x4d, 0x9a,
    0xe5, 0x5f, 0xee, 0x89, 0x6a, 0x10, 0xce, 0x70, 0x7c, 0x3e, 0xd7, 0xe7, 0x34, 0xe4, 0x47, 0x27,
    0xa3, 0x95, 0x74, 0x50, 0x1a, 0x53, 0x26, 0x83, 0x10, 0x9c, 0x2a, 0xba, 0xca, 0xba, 0x28, 0x3c,
    0x31, 0xb4, 0xbd, 0x2f, 0x53, 0xc3, 0xee, 0x37, 0xe3, 0x52, 0xce, 0xe3, 0x4f, 0x9e, 0x50, 0x3b,
    0xd8, 0x0c, 0x06, 0x22, 0xad, 0x79, 0xc6, 0xdc, 0xee, 0x88, 0x35, 0x47, 0xc6, 0xa3, 0xb3, 0x25,


I understand that:

T1_Modulus -> is a public key.

T1_PubExp -> Is the exponent.

What I don't understand is T1_PrivExp.

What's this? Maybe the private key?

If I've a private key in this format:


How I can calculate T1_PrivExp starting from it?

Many thanks.

  • 2
    $\begingroup$ Don't forget to follow up on your questions. And you may want to start learning RSA by looking at the algorithm, instead of starting coding without any knowledge of what you are doing. Because the latter, as StackOverflow has frequently shown me, is never secure. $\endgroup$
    – Maarten Bodewes
    Commented Apr 1, 2020 at 17:46

1 Answer 1


In RSA, the keys do not consist of a single value; they consist of multiple values:

  • the public key consists of the modulus and the public exponent;
  • the private key consists of the modulus and the private exponent.

So there are two exponents: one for the public and one for the private key. You perform modular exponentiation with the public exponent for encryption or verification and modular exponentiation with the private exponent for decryption or signature generation.

The public exponent is deliberately kept small to have more efficient public key operations. Generally it is just set to the fifth prime of Fermat, called F4. It only has two bits set to 1 to further optimize the calculations.

It might be that the more efficient Chinese Remainder Theorem (CRT) parameters are included in the private key. These are basically the parameters from which the modulus and exponents are derived such as the prime numbers P and Q. It is possible to speed up RSA private key calculations using these parameters. To speed calculations even more it may be that more than two prime numbers are used, resulting in multi-prime RSA.

Your posted RSA PRIVATE KEY is a private key whose format is specified in PKCS#1, which is the RSA standard used in most applications:

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

You can see its contents here. Alternatively you can view it using the command line openssl asn1parse:

    0:d=0  hl=4 l=1188 cons: SEQUENCE          
    4:d=1  hl=2 l=   1 prim: INTEGER           :00
    7:d=1  hl=4 l= 257 prim: INTEGER           :D75430BE504D406163BD9C496689A5488A596B85897375040DA621E7200F091A040B95499B8F4CB195348215CD3639EFE3426396EE9686F42860F454BAAEEEA3B274C753C519D76C869D77E7B3FA8EDAF9EBB7B401C40DD65828B5BE068158D3101E78AB87149FBC3F5DB8BCBB5B2200CB6594995B64D5C5570A53F3805B1888F4A829D6D8D3449DFA6E09C3799078A56DA2AB92E8AC2CF0DC67A158F8F453F99F71CEC2FAEA3736378DF7128E6518738DA6E4F2B0B686711A49E639E8B80D04018E1B6F608FE5E86072B2F27E4FD4BD2788F998B320762F8654B5EF9D7ACAD5F71AD8F64C46330932F45C4DF5FD2E932DE6A36786A7C82F5B755F4F7C4C08B3
  268:d=1  hl=2 l=   3 prim: INTEGER           :010001
  273:d=1  hl=4 l= 256 prim: INTEGER           :3ABBC81FE11F71341F5494D0A09B62EE0A6EA19967088B1E73EAA0CCBE3DDBA9B0F8C7DBB006C2509DF6189581C80CBD962B81A6A5A581620FB18273AA081527A98198ED0C9223E48243697555EE3E1114A26B153A7613A027A3D30EE60F59FF1822779FB1D4BA4D4AAB71BC690E4E9410E6C045A45C38C2FF1EDE0F492F8FDD2B54749B5403F17C25153F6B347AB7DFC034623EF7A94BD2907C31A833596FFD3C3D32788822D97C4403911DE89040CC6A96FD91C5172E853AE39A189645A1EA077E40B64CD203EF55542202C458E8016BDA31FE7B767B1EDC1304A1427450D58E605D08C297D6D50866B8BE51D04A567D8F77D4A6293CEF2C6C60D9DB272821
  533:d=1  hl=3 l= 129 prim: INTEGER           :F35A0E03E3A004A0E42A9FD1CC470492E0227654DB00B734EE45525866587C3F97948D7102B72CDCBFF2C68292423A23ADB75BFB0A7DF61C37B93EFF18664A0ADFA24353FFBF5E9E1BE03E766A87E7F0B50C19A94CE870A3E40B7CBDDDD091A7D940D181F3493F0876DBEAD275EFA27EE60C69A76599566B35FF14B95CDEF1BF
  665:d=1  hl=3 l= 129 prim: INTEGER           :E285460B8B85C62534B7DD312603555549723219E1541C250A81D3AA4A107B3B9A4DA9F3D0BD6A068E76F8674A20196B43D8BBE1ABEF886BA9E655D3C164D5985C4A03EBC0EE88C29A37F4DF6E2DD3CA286CFB13ECE0E9EA64734269BA50A46358238844DD6B42C15537C2CF62491005461B1B9E21A8D61EFA81802BF9F2BE0D
  797:d=1  hl=3 l= 129 prim: INTEGER           :DC25E3F7F0BC9A7352F69C8E9756C7F4777FB5BD1E428F7AFAF30B839D52FF542834E3A010ECD550FEF50A50A52FF498C256D6874CFE96DF002A3DAB58CF70BC5583DD94E8109FF03917AC6A44059EF64B531F03E1E785BF3E56860ADDD8096CE7459443136C77F198556B21EA3F57A9A5442570A2A10D64FFFC3B2B55B0FAD1
  929:d=1  hl=3 l= 128 prim: INTEGER           :78E68F2B2C4DBB23328F0C04E67812FC9155DCFDC9315E503ADA6E41CE841B72057A7C4240E0480DB5CE33E8D53C6AB4C0A2962CEDDACC2242AD4893DBFDD8AF185AFCDAC0BFCFC8A60D45AA5721289016A18C24E76268170D842327512527884A8BB478A50151C0E49DFD6138E12C26D473357B6215BE2B0CA33FE8B8E061A5
 1060:d=1  hl=3 l= 129 prim: INTEGER           :88EE8B43C85D95C6B0DA7E574D3DEA4769521535E41F2FC24883850164238AF30DB07D826829452345740B1D7CB1C689729A04A95FEAF5DD32AC1847148FC7BC503ED43DA2378F82B3A06D877972ADC01CB32B99F2504EF78759EE1A5D5E4776CFA4B2D2FE7957F7C6F60ED2683DBBCAEC55A296AA41832D38DFECEA61484102

As it is quite tricky to parse these kind of formats, it is best to use a library that already contains an codec. Implementing a full ASN.1 codec requires knowledge about compilers, parsers and code generation. It's interesting enough, but it is hard to do as well. Although it is relatively easy to hack one, you'll quickly find out that ASN.1 is used in a lot of cryptography related code, including e.g. RSA PKCS#1 v1.5 compatible signatures.

Note that PKCS#1 specifies a structure. This structure is encoded using BER / DER, the basic or distinguished encoding rules. These are however binary encodings. What you've specified is obviously text. This text is called PEM for privacy enhanced mail. Mail is a text format, so it cannot deal with binary. For that reason the binary is base 64 encoded and a header and footer line are added so that the type of key is known. OpenSSL uses this as default format for keys.

  • $\begingroup$ Nit: in the 1980s and 1990s email mostly couldn't handle binary so PEM needed base64. Nowadays with widespread MIME email usually can, but other common things like cut&paste and HTML can't. so the format remains useful. In fact, Stack posts are an almost canonical example of not handling binary! $\endgroup$ Commented Apr 2, 2020 at 0:20
  • $\begingroup$ That's cheating, MIME can just handle it because it encodes the binary itself :) And HTTP can certainly handle binary, even if HTML can't. $\endgroup$
    – Maarten Bodewes
    Commented Apr 2, 2020 at 0:24
  • $\begingroup$ MIME can encode (base64 or qp) if the channel requires it -- per hop -- but nowadays many channels don't -- even SMTP has an option for 8-bit-clean. Yes HTTP can handle binary -- using methods copied from MIME -- which is why I didn't cite it. $\endgroup$ Commented Apr 3, 2020 at 10:13

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.