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
  • 2

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
  • 147,019
  • 11
  • 229
  • 360
  • 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. – vdavid Mar 21 '22 at 12:59
  • @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. – poncho Mar 21 '22 at 13:14
  • 1
    @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. – fgrieu Mar 21 '22 at 13:56
  • @poncho SHA3 is theoretically better because, unlike SHA-256, I think we cannot use M and SHA3(M) to forge a SHA3(M||X) – vdavid Mar 21 '22 at 14:17
  • @fgrieu OK if the hash is an intermediate step, I guess the signature cannot be tampered – vdavid Mar 21 '22 at 14:19
  • 1
    @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. – fgrieu Mar 21 '22 at 14:25
  • 1
    @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). – vdavid Mar 21 '22 at 14:30
  • Actually it should be $\text{SHA256}(M || padding_1|| X)$ since the original hash has a padded and during extension SHA-256 calculates another padding. – kelalaka Mar 21 '22 at 20:34
  • @kelalaka: actually, I had included $padding_1$ in the $X$ - that's why I said it was for 'some X' - I didn't think the details of the length-extension attack was actually relevant - he's not attempting to perform the attack, instead, he is asking about the implications. – poncho Mar 21 '22 at 20:39
  • $M$ is the message that is free for all to verify the signature with it, Imho, this detail is still important. – kelalaka Mar 21 '22 at 20:44
  • @kelalaka I’d say the padding matters if the wrong padding makes RSA vulnerable to forge a valid signature for a tampered message. Is it something I should be concerned with? – vdavid Apr 04 '22 at 12:32
  • @vdavid: padding is being used in two different senses; one is some padding done as a part of the SHA256 computation (which is a detail that you don't need to be concerned with, unless you're implementing SHA256). The other is padding done after the hash and just before the raw RSA computation - that is important (getting it wrong would allow someone to generate forgeries), however it has nothing to do with length-extension attacks. – poncho Apr 04 '22 at 12:40
  • @poncho what kind of other forgeries could happen if I use the wrong padding? Is there a recommended padding? I’ve yet to choose one among PKCS (or any other that would be better for RSA). – vdavid Apr 04 '22 at 12:59