0
$\begingroup$

I need to sign a message using a private key and verify the message with a public key, while making sure the message hasn’t been tampered.

I know that SHA-256 itself is prone to length-extension attacks.

I also know that things like HMAC have been specifically designed to circumvent such attacks.

But what if I sign a message with RSA and SHA-256? Are they safe?

Do I need to sign the RSA/SHA3 to be protected? Or maybe truncated versions of SHA2 (namely SHA-384 and SHA-512/256) which are allegedly not susceptible to length-extension attacks?

Would HMAC be a better approach to this problem?

I’m considering using RSA which is probably the most famous among asymmetric cryptography. Feel free to point me to something else if there’s a better option. I need something supported by OpenSSL and the Node.js crypto module (which, as far as I know, is also based on OpenSSL).

PS. I’m a bit new to the crypto community, so I hope my words make sense.

-- addendum--

Here is my concern about RSA-SHA256.

Let’s say the message is $M$ and its hash is $SHA256(M)$.

An attacker can use them to compute $M||X$ and $SHA256(M||X)$, even without knowing the private key. In this case, the recipient of $M||X$ and its signature $SHA256(M||X)$ shall believe that the message is valid because the message and its signature do match.

At least that’s what happens if RSA_sign simply uses the raw hash. If RSA passes the hash through a HMAC-like technique or any algorithm that prevents the attacker from forging a signature, I guess we’re safe.

$\endgroup$
5

1 Answer 1

5
$\begingroup$

But what if I sign a message with RSA and SHA-256? Are they safe?

Length extension attacks are not a concern.

Here is what a length extension attack allows you do to: if you are given the hash $\text{SHA256}(M)$, but you don't know the original message $M$ (but you do know its length), then you can compute the value of the hash $\text{SHA256}(M || X)$ (where $||$ is bitstring concatenation, and for some values of the string $X$); the value of this hash will be different than the original hash.

So, why isn't this a concern:

  • When you have a signature of a known message $M$, you obviously know $M$; you can (should you want) compute $\text{SHA256}(M || X)$ for any string $X$ you want; you don't need a "length extension attack"

  • RSA signs the value $\text{SHA256}(M)$; the value $\text{SHA256}(M || X)$ will be different, and so if you replace $M$ with $M || X$, the signature will not verify

$\endgroup$
13
  • $\begingroup$ My concern is, the attacker knows M and SHA256(M), so he may compute M||X and SHA256(M||X) (even without knowing the private key). In this case, the recipient of M||X and its signature SHA256(M||X) will not know that the message was tampered because the altered message and its signature will match. Well, at least that’s what happens if RSA_sign simply uses the raw hash. If RSA passes the hash through a HMAC-like technique, I guess we’re safe. $\endgroup$
    – vdavid
    Mar 21, 2022 at 12:59
  • $\begingroup$ @vdavid: "so he may compute M||X and SHA256(M||X) (even without knowing the private key)." - how is that different from (say) SHA3? With SHA3, if he knows $M$ and selects $X$, he can compute SHA3(M||X). If you're thinking that SHA256(M||X) will be the same value as SHA256(M), well no, that's not how it works. $\endgroup$
    – poncho
    Mar 21, 2022 at 13:14
  • 1
    $\begingroup$ @vdavid: Your "the recipient of M||X and its signature SHA256(M||X)…" is in error. SHA256(M||X) is not the signature of M||X. It's an intermediary step in computing a signature of M||X, as a function of SHA256(M||X), private key, optional randomness. Among the three inputs of this function, only the private key is secret. Thus it is not an issue that SHA256(M||X) is easy to compute; it's a functional requirement. $\endgroup$
    – fgrieu
    Mar 21, 2022 at 13:56
  • 1
    $\begingroup$ @vdavid: you are correct that SHA3, unlike SHA-256, has no length-extension property. However you are incorrect in what that prevents. It prevents computing SHA3(M||X) from SHA3(M) unless one has complete knowledge of M (in the case of SHA-256, one further needs to restrict to some X with precisely the right start, dependent on the length of M). With knowledge of Mand X one can compute SHA3(M||X), for any M and X. Note: the Right Thing will be to accept poncho's answer by clicking on the tick. $\endgroup$
    – fgrieu
    Mar 21, 2022 at 14:25
  • 1
    $\begingroup$ @fgrieu You’re right. And because M is not secret in my case, I believe this property doesn’t give SHA3 a significant advantage over SHA-256 (at least, not from a length-extension point of view). $\endgroup$
    – vdavid
    Mar 21, 2022 at 14:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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