2
$\begingroup$

I am running a server that is receiving packets. Each packet is signed with an RSA 512 SHA-256 digital signature. I have a public key and exponent that I use to verify the digital signatures.

I'm currently trying to do this in Python using Cryptodome. I am able to verify signatures but am unable to get the original hash.

If verification is failed, I want to obtain the original hash that was signed. Is there a way to do this with the public key?

$\endgroup$
3
  • 1
    $\begingroup$ This is a perfect question for Stack Overflow with your minimal working code to show the problem and the question is tagged with cryptography, encryption, python(x), and cryptodome. $\endgroup$
    – kelalaka
    Dec 3 '20 at 19:40
  • $\begingroup$ Ok I will. Is the idea even possible though? $\endgroup$ Dec 3 '20 at 19:53
  • $\begingroup$ Ths signature is RSA-FDH or RSA-PSS? You need to provide all of the details. $\endgroup$
    – kelalaka
    Dec 3 '20 at 19:54
2
$\begingroup$

Yes, this is usually possible. You can use the RSA public key to:

  1. perform modular exponentiation using the public exponent and modulus (raw RSA, sometimes you can use raw RSA decrypt with the public key for this);
  2. interpret the result as unsigned big endian integer (usually this is already the case);
  3. perform the unpadding (usually this just means finding the hash within the padding).

Note that there are multiple RSA schemes possible, e.g. PKCS#1 v1.5 padding or PSS padding. It depends on the signature generation which one is used. For an insecure 512 bit key you would generally bet on PKCS#1 v1.5 padding.

You can find both schemes in the relatively readable PKCS#1 RFC which includes the full description of above steps. However, it ends with creating the padding from an existing hash instead and compare, you need to reverse the padding creation instead - this isn't hard for PKCS#1, but you would not be able to do it for PSS as the hashed (mHash) value is hashed again (to get a hash value H).

For PKCS#1 v1.5 padding the hash value is just the hLen bytes that are right before the last byte, where hLen is the hash size in octets / bytes. Of course you'd still have to validate the rest of the padding as well to perform full signature verification.


If you are very lucky then decryption with the public key while choosing the PKCS#1 decryption scheme will directly give you the hash. But note that decryption generally requires the private key and a different unpadding scheme (also generally referred to as PKCS#1 padding, but the padding for encryption is still different than that for signature generation). However, it may just choose the signature unpadding instead for compatibility reasons.

$\endgroup$
13
  • $\begingroup$ This is starting to make sense, I really appreciate this answer. So to make sure I'm understanding correctly, the digital signature has padding. Then the hash is somewhere contained in the padding and its location depends on the RSA scheme? $\endgroup$ Dec 3 '20 at 20:20
  • $\begingroup$ Well, yes for PKCS#1 v1.5 and a few other paddings, e.g. those for signature schemes with message recovery. However, for PSS the message hash is hashed again, and that is obviously impossible to reverse. $\endgroup$
    – Maarten Bodewes
    Dec 3 '20 at 20:28
  • $\begingroup$ I see. So if I can find a way to extract the padding from the signature, I should be easily able to find the hash inside of it. Thank you so much. I will look into this. $\endgroup$ Dec 3 '20 at 20:43
  • $\begingroup$ I see your edit, and I am sure that is some valuable information, but I have another question now. I am expecting my hash to be 32 bytes long. The entire digital signature is 64 bytes. So by the formula you gave, the hash I'm looking for would be 64 / 8 = 8 bytes, which can't be right. Could you maybe help me understand where my misunderstanding is? $\endgroup$ Dec 3 '20 at 20:51
  • $\begingroup$ No, I first wrote n, but hash len is in bits, so 256 / 8 = 32 bytes for the hash (which you already knew). Note that in cryptography, we generally list everything in bits, not bytes. Uh, except for the PKCS#1 spec, I suddenly remember. Sorry about that :) $\endgroup$
    – Maarten Bodewes
    Dec 3 '20 at 22:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.