Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RSA: Get exponent and modulus given a public key

I need to encrypt some data using RSA in JavaScript. All of the libraries around ask for an exponent and a modulus, yet I get a single public.key file from my opponent.

How do you retrieve the public exponent and modulus part from an RSA file?

like image 683
Pierre Spring Avatar asked Jun 25 '10 09:06

Pierre Spring


People also ask

What is the relation between the RSA public exponent and private exponent?

The public key consists of the modulus n and the public (or encryption) exponent e. The private key consists of the private (or decryption) exponent d, which must be kept secret. p, q, and λ(n) must also be kept secret because they can be used to calculate d.

What is the public exponent in RSA key?

The pair {n, e} is the public key. It is designed to be shared with everyone. The number e is called "public key exponent". It is usually 65537 (0x010001).


1 Answers

It depends on the tools you can use. I doubt there is a JavaScript too that could do it directly within the browser. It also depends if it's a one-off (always the same key) or whether you need to script it.

Command-line / OpenSSL

If you want to use something like OpenSSL on a unix command line, you can do something as follows. I'm assuming you public.key file contains something like this:

-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmBAjFv+29CaiQqYZIw4P J0q5Qz2gS7kbGleS3ai8Xbhu5n8PLomldxbRz0RpdCuxqd1yvaicqpDKe/TT09sR mL1h8Sx3Qa3EQmqI0TcEEqk27Ak0DTFxuVrq7c5hHB5fbJ4o7iEq5MYfdSl4pZax UxdNv4jRElymdap8/iOo3SU1RsaK6y7kox1/tm2cfWZZhMlRFYJnpoXpyNYrp+Yo CNKxmZJnMsS698kaFjDlyznLlihwMroY0mQvdD7dCeBoVlfPUGPAlamwWyqtIU+9 5xVkSp3kxcNcNb/mePSKQIPafQ1sAmBKPwycA/1I5nLzDVuQa95ZWMn0JkphtFIh HQIDAQAB -----END PUBLIC KEY----- 

Then, the commands would be:

PUBKEY=`grep -v -- ----- public.key | tr -d '\n'` 

Then, you can look into the ASN.1 structure:

echo $PUBKEY | base64 -d | openssl asn1parse -inform DER -i 

This should give you something like this:

    0:d=0  hl=4 l= 290 cons: SEQUENCE               4:d=1  hl=2 l=  13 cons:  SEQUENCE               6:d=2  hl=2 l=   9 prim:   OBJECT            :rsaEncryption    17:d=2  hl=2 l=   0 prim:   NULL                  19:d=1  hl=4 l= 271 prim:  BIT STRING  

The modulus and public exponent are in the last BIT STRING, offset 19, so use -strparse:

 echo $PUBKEY | base64 -d | openssl asn1parse -inform DER -i -strparse 19 

This will give you the modulus and the public exponent, in hexadecimal (the two INTEGERs):

    0:d=0  hl=4 l= 266 cons: SEQUENCE               4:d=1  hl=4 l= 257 prim:  INTEGER           :98102316FFB6F426A242A619230E0F274AB9433DA04BB91B1A5792DDA8BC5DB86EE67F0F2E89A57716D1CF4469742BB1A9DD72BDA89CAA90CA7BF4D3D3DB1198BD61F12C7741ADC4426A88D1370412A936EC09340D3171B95AEAEDCE611C1E5F6C9E28EE212AE4C61F752978A596B153174DBF88D1125CA675AA7CFE23A8DD253546C68AEB2EE4A31D7FB66D9C7D665984C951158267A685E9C8D62BA7E62808D2B199926732C4BAF7C91A1630E5CB39CB96287032BA18D2642F743EDD09E0685657CF5063C095A9B05B2AAD214FBDE715644A9DE4C5C35C35BFE678F48A4083DA7D0D6C02604A3F0C9C03FD48E672F30D5B906BDE5958C9F4264A61B452211D   265:d=1  hl=2 l=   3 prim:  INTEGER           :010001 

That's probably fine if it's always the same key, but this is probably not very convenient to put in a script.

Alternatively (and this might be easier to put into a script),

openssl rsa -pubin -inform PEM -text -noout < public.key 

will return this:

Modulus (2048 bit):     00:98:10:23:16:ff:b6:f4:26:a2:42:a6:19:23:0e:     0f:27:4a:b9:43:3d:a0:4b:b9:1b:1a:57:92:dd:a8:     bc:5d:b8:6e:e6:7f:0f:2e:89:a5:77:16:d1:cf:44:     69:74:2b:b1:a9:dd:72:bd:a8:9c:aa:90:ca:7b:f4:     d3:d3:db:11:98:bd:61:f1:2c:77:41:ad:c4:42:6a:     88:d1:37:04:12:a9:36:ec:09:34:0d:31:71:b9:5a:     ea:ed:ce:61:1c:1e:5f:6c:9e:28:ee:21:2a:e4:c6:     1f:75:29:78:a5:96:b1:53:17:4d:bf:88:d1:12:5c:     a6:75:aa:7c:fe:23:a8:dd:25:35:46:c6:8a:eb:2e:     e4:a3:1d:7f:b6:6d:9c:7d:66:59:84:c9:51:15:82:     67:a6:85:e9:c8:d6:2b:a7:e6:28:08:d2:b1:99:92:     67:32:c4:ba:f7:c9:1a:16:30:e5:cb:39:cb:96:28:     70:32:ba:18:d2:64:2f:74:3e:dd:09:e0:68:56:57:     cf:50:63:c0:95:a9:b0:5b:2a:ad:21:4f:bd:e7:15:     64:4a:9d:e4:c5:c3:5c:35:bf:e6:78:f4:8a:40:83:     da:7d:0d:6c:02:60:4a:3f:0c:9c:03:fd:48:e6:72:     f3:0d:5b:90:6b:de:59:58:c9:f4:26:4a:61:b4:52:     21:1d Exponent: 65537 (0x10001) 

Java

It depends on the input format. If it's an X.509 certificate in a keystore, use (RSAPublicKey)cert.getPublicKey(): this object has two getters for the modulus and the exponent.

If it's in the format as above, you might want to use BouncyCastle and its PEMReader to read it. I haven't tried the following code, but this would look more or less like this:

PEMReader pemReader = new PEMReader(new FileReader("file.pem")); Object obj = pemReader.readObject(); pemReader.close(); if (obj instanceof X509Certificate) {    // Just in case your file contains in fact an X.509 certificate,    // useless otherwise.    obj = ((X509Certificate)obj).getPublicKey(); } if (obj instanceof RSAPublicKey) {    // ... use the getters to get the BigIntegers. } 

(You can use BouncyCastle similarly in C# too.)

like image 104
Bruno Avatar answered Sep 22 '22 15:09

Bruno