1
$\begingroup$

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:

-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA11QwvlBNQGFjvZxJZomlSIpZa4WJc3UEDaYh5yAPCRoEC5VJ
m49MsZU0ghXNNjnv40Jjlu6WhvQoYPRUuq7uo7J0x1PFGddshp1357P6jtr567e0
AcQN1lgotb4GgVjTEB54q4cUn7w/Xbi8u1siAMtllJlbZNXFVwpT84BbGIj0qCnW
2NNEnfpuCcN5kHilbaKrkuisLPDcZ6FY+PRT+Z9xzsL66jc2N433Eo5lGHONpuTy
sLaGcRpJ5jnouA0EAY4bb2CP5ehgcrLyfk/UvSeI+ZizIHYvhlS17516ytX3Gtj2
TEYzCTL0XE31/S6TLeajZ4anyC9bdV9PfEwIswIDAQABAoIBADq7yB/hH3E0H1SU
0KCbYu4KbqGZZwiLHnPqoMy+PdupsPjH27AGwlCd9hiVgcgMvZYrgaalpYFiD7GC
c6oIFSepgZjtDJIj5IJDaXVV7j4RFKJrFTp2E6Ano9MO5g9Z/xgid5+x1LpNSqtx
vGkOTpQQ5sBFpFw4wv8e3g9JL4/dK1R0m1QD8XwlFT9rNHq338A0Yj73qUvSkHwx
qDNZb/08PTJ4iCLZfEQDkR3okEDMapb9kcUXLoU645oYlkWh6gd+QLZM0gPvVVQi
AsRY6AFr2jH+e3Z7HtwTBKFCdFDVjmBdCMKX1tUIZri+UdBKVn2Pd9SmKTzvLGxg
2dsnKCECgYEA81oOA+OgBKDkKp/RzEcEkuAidlTbALc07kVSWGZYfD+XlI1xArcs
3L/yxoKSQjojrbdb+wp99hw3uT7/GGZKCt+iQ1P/v16eG+A+dmqH5/C1DBmpTOhw
o+QLfL3d0JGn2UDRgfNJPwh22+rSde+ifuYMaadlmVZrNf8UuVze8b8CgYEA4oVG
C4uFxiU0t90xJgNVVUlyMhnhVBwlCoHTqkoQezuaTanz0L1qBo52+GdKIBlrQ9i7
4avviGup5lXTwWTVmFxKA+vA7ojCmjf0324t08oobPsT7ODp6mRzQmm6UKRjWCOI
RN1rQsFVN8LPYkkQBUYbG54hqNYe+oGAK/nyvg0CgYEA3CXj9/C8mnNS9pyOl1bH
9Hd/tb0eQo96+vMLg51S/1QoNOOgEOzVUP71ClClL/SYwlbWh0z+lt8AKj2rWM9w
vFWD3ZToEJ/wOResakQFnvZLUx8D4eeFvz5Whgrd2Als50WUQxNsd/GYVWsh6j9X
qaVEJXCioQ1k//w7K1Ww+tECgYB45o8rLE27IzKPDATmeBL8kVXc/ckxXlA62m5B
zoQbcgV6fEJA4EgNtc4z6NU8arTAopYs7drMIkKtSJPb/divGFr82sC/z8imDUWq
VyEokBahjCTnYmgXDYQjJ1ElJ4hKi7R4pQFRwOSd/WE44Swm1HM1e2IVvisMoz/o
uOBhpQKBgQCI7otDyF2VxrDafldNPepHaVIVNeQfL8JIg4UBZCOK8w2wfYJoKUUj
RXQLHXyxxolymgSpX+r13TKsGEcUj8e8UD7UPaI3j4KzoG2HeXKtwByzK5nyUE73
h1nuGl1eR3bPpLLS/nlX98b2DtJoPbvK7FWilqpBgy043+zqYUhBAg==
-----END RSA PRIVATE KEY-----

How I can calculate T1_PrivExp starting from it?

Many thanks.

$\endgroup$
  • 1
    $\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 Apr 1 at 17:46
2
$\begingroup$

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 encoder. Implementing a full ASN.1 decoder requires knowledge about compilers, parsers and code generation. It's interesting enough, but it is hard to do as well.


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.

| improve this answer | |
$\endgroup$
  • $\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$ – dave_thompson_085 Apr 2 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 Apr 2 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$ – dave_thompson_085 Apr 3 at 10:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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