I am doing AES CBC decryption in java using javax.crypto . I am using the following Cipher class methods:
public final void init (int opmode, Key key, AlgorithmParameters params) method for initialization,final int update(byte[] input, int inputOffset, int inputLen, byte[] output) method for decrypting the data,final int doFinal(byte[] output, int outputOffset) method to finish the decryption.My query is this: Can I assume that the size of the data returned to me by the doFinal call would always be less than or equal to the AES Block Size? The documentation describes the doFinal method as:
“Finishes a multi-part transformation (encryption or decryption). Processes any bytes that may have been buffered in previous update calls. The final transformed bytes are stored in the output buffer.”
But it nowhere says that the output buffer would contain at most one block of data. Though I understand that this is the general behaviour of AES APIs, and this is the behaviour my code has exhibited till now, but would this assumption always hold?
In general (as in, in the context of the Cipher class) I don't believe it would be safe to assume this. As per the javadocs for that doFinal method:
If the output buffer is too small to hold the result, a ShortBufferException is thrown. In this case, repeat this call with a larger output buffer. Use getOutputSize to determine how big the output buffer should be.
So if you're allocating the output buffer "near" the point where you call the doFinal method, then it would make sense to call getOutputSize and allocate an appropriately-sized buffer. Job done.
On the other hand, if you're passing in a buffer from "far away" that was created to be exactly the block size, you might be in more trouble. It would be perfectly legal (at least, according to the public interface of the Java class) for a Cipher implementation to return an output larger than the block size, so long as the getOutputSize method returns the appropriate size.
In fact, if you're doing CBC decryption, doesn't that require you to pass in all of the blocks to the update method? In which case, you should get the full plaintext output back from doFinal, not just a single block?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With