How to convert a raw module and exponent to an RSA public key (.pem format)

I have a module and an exponent of the RSA public key embedded in a binary, and I am trying to extract the entire blob and create a useful .pem public key.

I am currently extracting the full 260 bytes (4 bytes for exponent, 256 bytes for module) and encoding as base64. I do this using the following shell command:

tail -c $((filesize - start_of_key_data)) filename | head -c $size_of_key_data | base64 > outkey 

This gives me the following line:

 <<<<<< modulus & exponent extracted from binary file, base64-encoded >>>>>> tZyrQA6cZFJfVm6FyXwtZaLQYg8EecuO+ObrHTwc8JO+XrgnpNAdmlhbAEPxSNnjwhNnbYGYGL4F vzmnZXzZU71Key42HQPh1k2Zx1UDbrH5ciODKx1ZbuEx8K24SHnL1nY/H75hwhT/ZRRVGQDvYDT+ sgzw2vmV66+dflw1Zs8BLhqjLjczdHvjeVXsDRJ9Mvvd/dhFH8UlTf4JpLGya9nsNIfNBBIf1Lll RWwCTiEIbaOMgWcLjLV/2tk/j5Dra/oQnVf/2hVsEF/hXEx41YjeEW/warweoDVG7zaxrHEc/k/r ZCUCZKxf8nBKdqax/gRICvkG6e5xg2GQw0W/ZwABAAE= 

Now, when I take the key keypair key.pem, the originally extracted module and exponent, and display the public part like this

 openssl rsa -in key.pem -pubout -out pubkey.pem 

I get this line (I skipped the header and footer lines:

 <<<<<<<<< valid public key data extracted from keypair >>>>>>>>> MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtZyrQA6cZFJfVm6FyXwt ZaLQYg8EecuO+ObrHTwc8JO+XrgnpNAdmlhbAEPxSNnjwhNnbYGYGL4FvzmnZXzZ U71Key42HQPh1k2Zx1UDbrH5ciODKx1ZbuEx8K24SHnL1nY/H75hwhT/ZRRVGQDv YDT+sgzw2vmV66+dflw1Zs8BLhqjLjczdHvjeVXsDRJ9Mvvd/dhFH8UlTf4JpLGy a9nsNIfNBBIf1LllRWwCTiEIbaOMgWcLjLV/2tk/j5Dra/oQnVf/2hVsEF/hXEx4 1YjeEW/warweoDVG7zaxrHEc/k/rZCUCZKxf8nBKdqax/gRICvkG6e5xg2GQw0W/ ZwIDAQAB 

You can see that the key data I extracted and base64-encoded are actually present in the data of the valid public key data extracted from key.pem using openssl. However, at the beginning there are 45 characters that my own extracted data does not have -

 MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA 

and the last 8 characters are also different.

 ZwIDAQAB 

Can someone offer some tips on how to convert a module and metric to a usable public key?

(The goal is to do this in a bash script, and not in python or C, as I have seen, many suggest.)

+5
source share
1 answer

The command you used, openssl rsa -in key.pem -pubout -out pubkey.pem , creates an ASN.1 structure as follows:

 SEQUENCE(2 elem) SEQUENCE(2 elem) OBJECT IDENTIFIER 1.2.840.113549.1.1.1 NULL BIT STRING(1 elem) SEQUENCE(2 elem) INTEGER(2048 bit) 229263895356027367204242482830890190076375310244080661230946245232688… INTEGER 65537 

(You can see the structure using openssl asn1parse -in pubkey.pem or using the ASN.1 online decoder .)

Content:

  • fixed header (contains all bytes, indicating the encoding of the whole sequence plus the encoding of the module)
  • module
  • specifying the exponent encoding
  • indicator

If you correctly assembled the exponent modules and bytes, you can build a public key in a form that OpenSSL understands by combining these four things. You already have the first longer heading. 'Middle heading' is '02 03 ':

  • '02 'for an integer
  • the length of the integer is 3 bytes (65537 = 01 00 01)

If your module is 2048 bytes and an exponent of 3 bytes (so that the length fields remain valid), a PEM file can be created by combining these four:

 <header> <modulus> 0x02 0x03 <exponent> 

This is why the last bytes of the binary dump are different from the OpenSSL output: the extracted 260 bytes do not contain 02 03 , but instead write 65537 as 00 01 00 01 (not 01 00 01 as in ASN.1 encoding).

To summarize, you can create a PEM file as follows:

Convert the extracted module + exponent back from base64 and extract them (note the byte offset 257 to skip the initial zero byte 65537!):

 echo 'tZyrQA6cZFJfVm6FyXwtZaLQYg8EecuO+ObrHTwc8JO+XrgnpNAdmlhbAEPxSNnjwhNnbYGYGL4FvzmnZXzZU71Key42HQPh1k2Zx1UDbrH5ciODKx1ZbuEx8K24SHnL1nY/H75hwhT/ZRRVGQDvYDT+sgzw2vmV66+dflw1Zs8BLhqjLjczdHvjeVXsDRJ9Mvvd/dhFH8UlTf4JpLGya9nsNIfNBBIf1LllRWwCTiEIbaOMgWcLjLV/2tk/j5Dra/oQnVf/2hVsEF/hXEx41YjeEW/warweoDVG7zaxrHEc/k/rZCUCZKxf8nBKdqax/gRICvkG6e5xg2GQw0W/ZwABAAE=' | base64 -d > modulus-exp.bin dd if=modulus-exp.bin of=modulus.bin bs=1 count=256 dd if=modulus-exp.bin of=exponent.bin bs=1 skip=257 count=3 H75hwhT / ZRRVGQDvYDT + sgzw2vmV66 + dflw1Zs8BLhqjLjczdHvjeVXsDRJ9Mvvd / dhFH8UlTf4JpLGya9nsNIfNBBIf1LllRWwCTiEIbaOMgWcLjLV / 2tk / j5Dra / oQnVf / 2hVsEF / hXEx41YjeEW / warweoDVG7zaxrHEc / k / rZCUCZKxf8nBKdqax / gRICvkG6e5xg2GQw0W / ZwABAAE =' | echo 'tZyrQA6cZFJfVm6FyXwtZaLQYg8EecuO+ObrHTwc8JO+XrgnpNAdmlhbAEPxSNnjwhNnbYGYGL4FvzmnZXzZU71Key42HQPh1k2Zx1UDbrH5ciODKx1ZbuEx8K24SHnL1nY/H75hwhT/ZRRVGQDvYDT+sgzw2vmV66+dflw1Zs8BLhqjLjczdHvjeVXsDRJ9Mvvd/dhFH8UlTf4JpLGya9nsNIfNBBIf1LllRWwCTiEIbaOMgWcLjLV/2tk/j5Dra/oQnVf/2hVsEF/hXEx41YjeEW/warweoDVG7zaxrHEc/k/rZCUCZKxf8nBKdqax/gRICvkG6e5xg2GQw0W/ZwABAAE=' | base64 -d > modulus-exp.bin dd if=modulus-exp.bin of=modulus.bin bs=1 count=256 dd if=modulus-exp.bin of=exponent.bin bs=1 skip=257 count=3 

Create headers:

 echo 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA' | base64 -d > header.bin echo '02 03' | xxd -r -p > mid-header.bin 

Combine them together:

 cat header.bin modulus.bin mid-header.bin exponent.bin > key.der 

Convert to PEM:

 openssl pkey -inform der -outform pem -pubin -in key.der -out key.pem 

Verify that you get the working key by checking it with an ASN.1 decoder or

 openssl asn1parse -in key.pem openssl asn1parse -in key.pem -strparse 19 
+9
source

Source: https://habr.com/ru/post/1209554/


All Articles