0

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.

vdavid
  • 103
  • 3

1 Answers1

5

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

poncho
  • 154,064
  • 12
  • 239
  • 382