我正在使用javax.crypto在Java中进行AES CBC解密.我正在使用以下Cipher类方法:
> public final void init(int opmode,Key key,AlgorithmParameters params)方法进行初始化,
>最终的int update(字节[]输入,int inputOffset,int inputLen,byte []输出)方法,用于解密数据,
>最后,我调用最终的int doFinal(byte []输出,int outputOffset)方法来完成解密.
我的查询是:我可以假设doFinal调用返回给我的数据大小始终小于或等于AES块大小吗?该文档将doFinal方法描述为:
“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.”
但是,没有地方说输出缓冲区最多包含一个数据块.尽管我知道这是AES API的一般行为,并且这是我的代码到目前为止所表现出的行为,但是这种假设是否始终成立?
解决方法:
总的来说(例如在Cipher类的上下文中),我认为假设这样做是不安全的.按照该doFinal方法的javadocs:
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 07001 to determine how big the output buffer should be.
因此,如果在调用doFinal方法的位置“附近”分配输出缓冲区,则调用getOutputSize并分配适当大小的缓冲区是有意义的.任务完成.
另一方面,如果要从“远”缓冲区传入一个恰好是块大小的缓冲区,则可能会遇到更多麻烦.只要getOutputSize方法返回适当的大小,Cipher实现返回大于块大小的输出是完全合法的(至少根据Java类的公共接口).
实际上,如果您要进行CBC解密,这是否不要求您将所有块都传递给update方法?在这种情况下,您应该从doFinal获得完整的纯文本输出,而不仅仅是一个块?