My question is closely related to Why do you need message authentication in addition to encryption?

Specifically I am interested in symmetric-key cryptography. I understand that attackers may modify cryptographic messages and the resulting decryption will be an altered message, MACs are designed to solve this. I read that one should create the cryptogram then generate a MAC from the cryptogram and send them together.

My question is why couldn't one simply append the original unencrypted message with a cryptographic hash of the original message and then encrypt them together? Then the receiver could decrypt both and verify the hash. If the cryptogram was altered the internal hash would no longer match and wouldn't it be hard to alter the message and/or internal hash such that they remain consistent since they are both encrypted?


Appending the hash then encrypting the whole lot is not necessarily secure. Actually, depending on the encryption system, it may be awfully weak. For instance, suppose that encryption is done with a stream cipher such as RC4: encryption is done by XORing with a key-dependent pseudorandom stream. Thus, the attacker sees this:

   E = (m || h(m)) XOR S(K)

where m is the message, h is the hash function, and S(K) is the pseudorandom stream generated from key K. If the attacker guesses the value of m (from context), then he can recompute h(m), and then obtain:

   S(K) = (m || h(m)) XOR E

Then, the attacker chooses his own message m', with arbitrary contents, and send:

   E' = (m' || h(m')) XOR S(K)

and voilà! Integrity has been defeated.


I just became familiar with the Padding Oracle attack outlined in the article you linked, and I believe you answered your own question. If the Padding Oracle attack can lead to full discovery of the plain-text, encrypting the unencrypted message message AND the hash would still require padding, and thusly make it vulnerable to discovery.

To implement both, you would probably want to hash the original message, append them together, encrypt it, and then hash the resulting ciphertext and append that to your encrypted combination. That would achieve what you want, but it seems to be a lot of work when the original solution seems perfectly acceptable.


On one hand, it's inefficient. The receiver would have to go through all the work of looking up the key, decrypting the message before learning if it was even worth decrypting it.

Similarly, it adds risk. If the MAC doesn't compute, the receiver would never even retrieve the keys needed to decrypt the message, and the receiver wouldn't ever have your payload. This could be critical if the payload was malicious.

Consider this scenario. Let's say your application is a web service that accepts new drawings from artists around the world who work for you. All your artists have been issued signing keys for their work, and use your public key to encrypt them to send them to you. And let's say that your server was vulnerable to malicious WMF files.

I'm an attacker, so I craft a malicious WMF, create some random bytes for the MAC, encrypt the file, and upload it to your server. Your server decrypts the WMF file, and saves it in order to compute the MAC. But your server's indexing tool reads the intermediate WMF, and executes the malware contained in the previewer, and so you get hacked anyway.* Note that this happens even though you haven't verified the MAC yet.

If you checked the MAC first, you wouldn't have decrypted the payload, and wouldn't exposed yourself to the malware in the WMF file.

*Yes, the indexer being compromised by WMF files was a real vulnerability on Windows. It is foolhardy to assume that a system is perfectly free of all vulnerabilities.

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