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?
This question is related to
openssl
rsa
public-key
If you need to parse ASN.1 objects in script, there's a library for that: https://github.com/lapo-luchini/asn1js
For doing the math, I found jsbn convenient: http://www-cs-students.stanford.edu/~tjw/jsbn/
Walking the ASN.1 structure and extracting the exp/mod/subject/etc. is up to you -- I never got that far!
Apart from the above answers, we can use asn1parse
to get the values
$ openssl asn1parse -i -in pub0.der -inform DER -offset 24
0:d=0 hl=4 l= 266 cons: SEQUENCE
4:d=1 hl=4 l= 257 prim: INTEGER :C9131430CCE9C42F659623BDC73A783029A23E4BA3FAF74FE3CF452F9DA9DAF29D6F46556E423FB02610BC4F84E19F87333EAD0BB3B390A3EFA7FB392E935065D80A27589A21CA051FA226195216D8A39F151BD0334965551744566AD3DAEB53EBA27783AE08BAAACA406C27ED8BE614518C8CD7D14BBE7AFEBE1D8D03374DAE7B7564CF1182A7B3BA115CD9416AB899C5803388EE66FA3676750A77AC870EDA027DC95E57B9B4E864A3C98F1BA99A4726C085178EA8FC6C549BE5EDF970CCB8D8F9AEDEE3F5CFDE574327D05ED04060B2525FB6711F1D78254FF59089199892A9ECC7D4E4950E0CD2246E1E613889722D73DB56B24E57F3943E11520776BC4F
265:d=1 hl=2 l= 3 prim: INTEGER :010001
Now, to get to this offset,we try the default asn1parse
$ openssl asn1parse -i -in pub0.der -inform DER
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
We need to get to the BIT String part, so we add the sizes
depth_0_header(4) + depth_1_full_size(2 + 13) + Container_1_EOC_bit + BIT_STRING_header(4) = 24
This can be better visialized at: ASN.1 Parser, if you hover at tags, you will see the offsets
Another amazing resource: Microsoft's ASN.1 Docs
I manage to find the answer for this solution, have to do javascript injection for this to install atob
const atob:any = require('atob');
asn1(pem: any){
asn1parser.Enc.base64ToBuf = function (b64:any) {
return asn1parser.Enc.binToBuf(atob(b64));
};
const dertest = asn1parser.PEM.parseBlock(pem).der;
var hex = asn1parser.Enc.bufToHex(asn1parser.PEM.parseBlock(pem).der)
var buf = asn1parser.ASN1.parse(dertest);
var asn1 = JSON.stringify(asn1parser.ASN1.parse(dertest), asn1parser.ASN1._replacer, 2 );
Mostly for my own reference, here's how you get it from a private key generated by ssh-keygen
openssl rsa -text -noout -in ~/.ssh/id_rsa
Of course, this only works with the private key.
Beware the leading 00 that can appear in the modulus when using:
openssl rsa -pubin -inform PEM -text -noout < public.key
The example modulus contains 257 bytes rather than 256 bytes because of that 00, which is included because the 9 in 98 looks like a negative signed number.
Source: Stackoverflow.com