Search code examples
javaencryptioncrc

CRC check redundant when using encryption?


I am using AES for encryption and CRC to check data integrity and I have the impression that the CRC check is redundant in my case. I am doing the following:

Encryption:

  1. Take the payload data and calculate CRC from it
  2. Encrypt payload data plus CRC

Decryption:

  1. Decrypt data
  2. Calculate new CRC of payload data and compare it with the old CRC

I wanted to provoke a CRC check failure in my unit test but when I manipulate the payload data the decryption always throws a BadPaddingException.

My question is: If the decryption always throws this exception when data is corrupted or manipulated (will it?) isn´t the CRC check redundant the way I am using it?


Solution

  • Assuming the incorrectly decrypted data is uniformly distributed, it will appear to be correctly PKCS5/PKCS7 padded about 1 time for every 255 incorrect passwords. This means that there is still a 1/255 chance that a correct change will occur and the item will decrypt into garbage. Therefore your check is not a waste.

    If you actually want the behavior you expected, you can use "AES/CTR/NoPadding", which will not require an exact block size and will always return a decrypted byte[], whether or not the keys match.

    However if an attacker can repeatedly alter the ciphertext and get you to decrypt it, (an example might be encrypted data stored in a cookie) and if they can distinguish between your behavior when the decrypted data throws an exception for bad padding and when it is simply garbage, then they can determine the plaintext via a "padding oracle attack".

    You may also want to consider if a more robust fingerprint than CRC may be appropriate like SHA-256 for ensuring message integrity.

    A lot of this is repeated from: AES BadPaddingException