|
Hi,
The problem: I wanted to compress data, then encrypt it with a block cipher using CAPI. However CryptEncrypt is constrained to an integral number of blocks (and that’s Microsoft’s CSP). Even though I start with an integral number of blocks, after Gzipping them (with message end flag – so I get some output) we obviously have a non-integral number of blocks. That is not a big problem, since I can Gzip::Get only as much as I need (in theory), or get all the output bytes, and save the remainder for encrypting with the next batch.
In the end, that’s what I did. I even put a DWORD with the length of the compressed block into the encryption stream.
At the other end, I carefully fed Gunzip the correct number of bytes, and set the message-end flag. Of course, the first batch is OK, but after that Gunzip just returns 0xa as MaxRetrievable. Even if I call GetNextMessage – this doesn’t help.
Finally I gave up, and used Mark Adler &c’s ZLIB library. Here, on the encryption side, I was forced to save the tail as before, but there was no need to keep track of the size of the batches sent / received from the compression engine. On the decryption side, I fed it as much data as I wanted (whatever came back from CryptDecrypt), and simply looped, taking the resulting bytes out until decompression was finished on that lot of data. I used ZLIB’s Z_SYNC_FLUSH flag on each call (except the last).
Is there something I’m missing with Gzip? Or is the action on message-end different from Z_SYNC_FLUSH. ZLIB has three levels of flushing: Z_SYNC_FLUSH, Z_FULL_FLUSH, and Z_FINISH. I used the first on each batch of data, for compressing (otherwise it doesn’t output anything) and decompressing.
If I wasn’t constrained to CAPI I could chain Gzip and CBCPaddedEncryptor – and I suppose it would be OK then.
- Shalom Crown
Shalom M. Crown, R&D Manager, TVG Technologies Ltd.
|
<<image001.gif>>
