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?
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.
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).
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.
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)
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.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With