1

I do this in bash:

head -c 128 <signed_fw_image> > <image_sign>

openssl rsautl -verify -inkey <public_rsa_key> -in <image_sign> -pubin > <out_sign_result>
md5sum <raw_image_bin> | xxd -r -p > <out_orig_result>
diff <out_sign_result> <out_orig_result>

How I can implement this in python and which libraries should I use?

jww
  • 97,681
  • 90
  • 411
  • 885
  • Have you tried anything at all? Any research? Read any documentation? – Maritim Aug 31 '17 at 11:40
  • Of course I do some research. For example we have openssl implementation in python, Crypto library. As example I have tried this https://stackoverflow.com/questions/12146985/verify-signature-with-pyopenssl So, I decided to ask this. Maybe someone do this before and can help me with this. I have read stackoverflow from 2008 and it helps me a lot. But now I'm doubt and this is my first question. – md5checksum Aug 31 '17 at 11:51
  • Which result did you get using the linked SO QA - seems the right approach? – stovfl Aug 31 '17 at 15:36
  • 1
    Perhaps you should take a look at the source code for the `rsautil` subcommand. You can find it at [`/apps/rsautil.c`](https://github.com/openssl/openssl/blob/master/apps/rsautl.c). Its one of the easier subcommands to parse and understand. – jww Aug 31 '17 at 18:07
  • Thanks! I have think about your solution, but for now I will try to use subprocess and catch bytes from stdout of rsautil. – md5checksum Sep 01 '17 at 06:02
  • I will try to answer on my question, using source of rsauitl later. – md5checksum Sep 01 '17 at 06:39

1 Answers1

0

I had a similar problem recently and I came by here on my way to eventually read the rsautl source code. It does just a single raw RSA round. The following Python 3 script can be used to reproduce the behavior of rsautl -verify and relies on the pycryptodome package, which I recommend for this task:

# emulates the command: openssl rsautl -verify -pubin -inkey $1

import sys
import re
from Crypto.PublicKey import RSA

with open(sys.argv[1], 'rb') as keyfile:
    key = RSA.import_key(keyfile.read())

msg = sys.stdin.buffer.read()
assert len(msg) <= key.size_in_bytes(), 'block too large.'

msg = int.from_bytes(msg, byteorder='big')

# RSA happens here:
dec = pow(msg, key.e, key.n)

dec = dec.to_bytes(key.size_in_bytes(), byteorder='big')
dec = re.match(BR'^\x00\x01\xFF+\x00(.*)$', dec, flags=re.DOTALL)
assert dec, 'output format invalid'

sys.stdout.buffer.write(dec.group(1))

I assume that this was the tricky part, you can compute the MD5 checksum of your file by using the builtin hashlib module.

Jesko Hüttenhain
  • 1,278
  • 10
  • 28