Reputation: 2884
I'm trying to encrypt files using CipherInputStream. I want to add a progress bar during the encryption.
The problem is that the ciphertext doesn't seem to be the same length as the file. It means I cannot know when cipherInputStream.read(bytes) is going to return -1.
How to know that in advance?
Upvotes: 2
Views: 72
Reputation: 94058
It depends on the mode of operation, so the stream itself won't tell you this. Generally however, when using a symmetric cipher, the size of the ciphertext should only be one block more at the maximum. So in general for long ciphertext, only displaying the full 100% may be an issue (but then you're done, right?).
For CTR mode, there is no overhead.
For ECB or CBC mode with PKCS#7 padding ("PKCS5Padding"
in Java) the overhead is maximum one full block and at minimal one byte. You can calculate the amount of padding by using:
int n = cipher.getBlockSize();
int pad = n - plaintextSize % n;
For GCM mode the authentication tag is included, which defaults to 16 bytes.
For all modes except ECB, the IV may be prefixed to the ciphertext.
Great, that's my direct answer. Let's invalidate it.
Don't use CipherInputStream
to encrypt. Use CipherOutputStream
to encrypt instead. That way you know exactly when everything ends: when the last block of the original input stream has been encrypted. After all, you don't need encrypted ciphertext in your application, right? See this related answer about encoding / decoding.
Upvotes: 1