to hash or not to hash? (and when!?)
hey all,
i am thinking -in theory (although i am implementing it in parallel) - the following thing. I have a communication between a client and a server and i want to protect all the messages from modification and authentication. Lets say that the server creates a message and wants to sent it securely to the client.. when should it hash it?
Case 1: It hashes the original (plaintext) message and then it encryptes the message and the hashed value (with the public key of the client) and sents the encrypted (object) packet to the other side.
Case 2: it encrypts the original message and it hashes the encrypted outcome and then sends the encrypted message with the hashed calculated value (which is unencrypted) .
In the first case, and if a someone wants to tamper the message, he will tamper the encrypted packet and thus the decryption will not take place correctly in the client's size(what is the use of the hash here?) Moreover, if the client decrypts the received packet correctly there is no use of checking the hash value.. In the second case even if the client produces its own hashed value of the encrypted message there is no use because even if someone changes the value of the hash or the encrypted packet then again the decryption will fail...
the question is...what and when do you hash? the original text and then you encrypt the message and the hashed value, or do you encrypt the message and then produce a hash from it?
i am looking for a conversation if anyone wants to discuss this issue...
thx a looooot!
[1581 byte] By [
panosjavaa] at [2007-11-26 20:32:06]

# 1
I believe the general rule is to hash before you encrypt. You want to authenticate what you meant to say.
# 2
hmm, yes but why should i hash something in the first place? i mean, why shouldn't i encrypt a message with my private key (in order to prove authenticity) and then encrypt the outcome with the public key of the receiver (in order to provide confidentiality..)
if anyone tampers the packet being sent (i mean changing some bits) the decryption will just fail... so what is the point of hashing in the above scenario?
# 3
Under certain conditions the actual hash value is admissible in a court of law as a 'digital signature', i.e. it provides legal-strength non-repudiation.Encrypting with your private key, which most APIs don't support BTW, doesn't have this property.
ejpa at 2007-7-10 1:22:18 >

# 4
so...its a legal issue in the end? it doesn't offer something to the technical part of an application? e.g. in the above scenario the hash does not provide identify the modification..because any modification is going to spoil the decryption....
# 5
> the hash does not provide identify the modificationEh?
ejpa at 2007-7-10 1:22:18 >

# 6
> > the hash does not provide identify the modification
>
> Eh?
ehm...you shouldn't quote just a part of a line..on its own..;-P
what i am saying is that in the case of signing a text (hashing the text and then ecrypting the hash with my private key) and then encrypting the whole object with the public key of the receiver...the hash does not provide in the end something...because if someone intercepts, he could modify the encrypted text and then the encryption on the receiver's side will fail..
# 7
I think the following is wrong:
> and thus the decryption will not take place correctly in the client's size
The decryption of encrypted and padded and tampered data mostly fails with a BadPaddingException, but the probability of succesfully decrypting tampered data is maybe 1% or something like that. Of course, you will probably get just pure garbabe, but it may be dangerous to your application.
> ts a legal issue in the end? it doesn't offer something to the technical part of an application?
No, it's a technical feature, which sometimes may have legal consequences. If you do not use a certificate issued by a public CA, then it is pure technics without any legal meaning.
If you just want to prevent tampering, then use hashing. I'm currently working on the following:
- digest = SHA(plaintext)
- signedDigest = RSA_encrypt(digest, myPrivateKey)
- secretKey = a random key
- encryptedSecretKey = RSA_encrypt(digest, hisPublicKey)
- ciphertext = AES_encrypt(plaintext, secretKey)
and I sent encryptedSecretKey, ciphertext and signedDigest.
I'm not completelly sure about this schema. I'm looking forward to any comments.
This schema supposes, that I know the public key of the receiver and vice versa (and that we both are sure about the public keys).
# 8
> I think the following is wrong:
>
> > and thus the decryption will not take place
> correctly in the client's size
>
> The decryption of encrypted and padded and tampered
> data mostly fails with a BadPaddingException, but the
> probability of succesfully decrypting tampered data
> is maybe 1% or something like that. Of course, you
> will probably get just pure garbabe, but it may be
> dangerous to your application.
so..in the end, we agree on that! if anyone tampers the message the decryption will fail and thus you do not care for the hashed version that is in there...
> > ts a legal issue in the end? it doesn't offer
> something to the technical part of an
> application?
>
>
> If you just want to prevent tampering, then use
> hashing. I'm currently working on the following:
> - digest = SHA(plaintext)
> - signedDigest = RSA_encrypt(digest, myPrivateKey)
> - secretKey = a random key
> - encryptedSecretKey = RSA_encrypt(digest,
> hisPublicKey)
> - ciphertext = AES_encrypt(plaintext, secretKey)
> and I sent encryptedSecretKey, ciphertext and
> signedDigest.
>
> I'm not completelly sure about this schema. I'm
> looking forward to any comments.
>
> This schema supposes, that I know the public key of
> the receiver and vice versa (and that we both are
> sure about the public keys).
hm..this looks good to me... i also use the "both sides know and are sure about each others certificates...keys..."...
i am having a technical problem though.. i have an object and in a variable i have the ciphertext and the signature of it (signed with my private key). I then want to encrypt the whole object (using the SealedObject) and by using RSA...but it keeps saying to me that the object is larger than it should be... which is less than 117 bytes!!! isn't that toooo small?
probably i will post a new post for that...:///
# 9
> so..in the end, we agree on that! if anyone tampers
> the message the decryption will fail and thus you do
> not care for the hashed version that is in there...
I don't agree. There is a not so small chance that the encryption will not fail if someone modifies the encrypted message. One will only get a BadPaddingException if the corruption results in a bad padding (obviously).
For PKCS5 padding the valid paddings are last byte == 1, last two bytes == 2, last 3 bytes == 3 etc. Based on this, for a random change to some bytes and using something like CBC mode with PKCS5 padding there is a better than 1 in 256 chance of NOT getting a BadPaddingException even though the cypher text has been modified. This is too large for safety for most people.
For PKCS1 padding there is probably a smaller chance of not getting a BadPaddingException but at this time I can't be bothered to calculate it.
# 10
> > > the hash does not provide identify the
> modification
> >
> > Eh?
>
> ehm...you shouldn't quote just a part of a line..on
> its own..;-P
OK, here's the whole thing:
> e.g. in the above scenario the hash does not provide identify the modification ...
That still doesn't make any sense to me. Maybe the problem is with what you wrote, not how I quoted it?
Anyway as sjasja has said, the chances of somebody modifying the cryptotext and getting away with it are quite high. The chances of somebody modifying the cryptotext and the hash and getting away with it are negligibly small.
ejpa at 2007-7-10 1:22:18 >

# 11
hmm !!sounds more clear to me now, thanks!
# 12
> so..in the end, we agree on that! if anyone tampers the message the decryption will fail and thus you do not care for the hashed version that is in there...
We do NOT agree. As I and sabre150 write, you may not rely on BadPaddingException as it is quite possible to get a good padding. The chance is too high for any security-related concern.
# 13
hmm yes ok martin, but i got the meaning from the explanation that sabre used.. could anyone give me a good reference for the above mentioned issue? (that i can tamper the encrypted message and thought the decryption will not fail....)i mean a url or a pdf or something...
# 14
Maybe my explanation wasn't clear enough.
I haven't seen any reference for this. But I think, it's very simple:
If you use a stream cipher (e.g. RC4), there is no padding and it will NEVER fail.
If you use a cipher in ECB mode (not recommended), it will also NEVER fail, except if you use tamper the padding itself.
If you use a cipher without padding (you can do it if you know the length of plaintext), it will also NEVER fail.
If you use any cipher, you can simply try it. With a few thousends tries (i.e., within a second or about) you will get a case with no BadPaddingException occuring.
Ciphers was NOT designed to prevent tampering, just to hide information.
# 15
This scheme doesn't protect the confidentiality of short messages. You need to encrypt the signedDigest also.
# 16
Do you mean the following:
- digest = RSA_decrypt(digest, myPublicKey);
guess plaintext, so that
- digest = SHA(plaintext)
holds?
Otherwise, please elaborate on this (or point me to a reference ).
You're right. I think , the following would work as well:
- secretKey = a random key
- digest = SHA(plaintext + secretKey)
- signedDigest = RSA_encrypt(digest, myPrivateKey)
- encryptedSecretKey = RSA_encrypt(digest, hisPublicKey)
- ciphertext = AES_encrypt(plaintext, secretKey)
# 17
I was thinking that you could AES_encrypt the digest along with the plaintext, but other approaches may also work.
Actually, I prefer to use something that has already been invented and analyzed. For example, there's no way I am going to outsmart the designers and analyzers of SSL/TLS, or the PKCS, or OpenPGP, or IKE. If it's absolutely impossible to use some established standard like these, then at least use them as guides. For example, SSL and IKE feature keyed hashes for integrity checking; these would not have the problem I mentioned.
# 18
You're right, I should either use an establish solution or try harder to understand it.Btw., I just found message-authentication codes claiming to be better (faster and more secure) than HMAC: http://cr.yp.to/mac.html