I usually prefer an approach where the CRC exception is excluded from the check. But if this is not possible for some reason, there is a workaround:
You need to reserve 8 bytes, 4 for CRC and 4 for compensation data. First, fill the reserved bytes with a specific dummy value (say 0x00 ). Then calculate the CRC in the first 4 bytes and finally change the remaining 4 bytes so that the CRC of the file remains the same.
More on how to perform this calculation: Reversible CRC32
I actually used this in one of my projects :
I was developing a zip based file format. The first file in the archive is stored uncompressed and serves as the header file. It also means that it is stored at a fixed offset in the file. It is still pretty standard and similar, for example, ePub.
Now I decided to include the hash in sha1 in the header to give each file a unique identifier based on the content and integrity check. Since the header and thus the sha1 hash are at a known offset in the file, masking it when the hashing is trivial. So I put a dummy hash and create a zip file, then a hash file and populate the real hash.
But now there is a problem: Zip stores the CRC of all contained files. And not only in one place, which is easy to mask during sha1 hashing, but in second place with a variable offset closer to the end of the file. So I decided to go with CRC rigging, so I got my strong hash, and zip gets its valid CRC32.
And since I already faked CRC for the final file, I decided that faking it for the original header file would not hurt either. Thus, all files in this format now start with a header file with CRC 0xD1CE0DD5 .
source share