1

有谁知道是否可以使用javax.crypto.Cipher类用任意数量的加密数据逐步填充固定大小的 ByteBuffers(池化缓冲区)的顺序链?也就是说,无需分配和填充任何其他中间缓冲区数组。我的特殊情况的加密是 CBC 模式下的 AES。

我希望有类似于 CharsetEncoder 的 encode(CharBuffer input, ByteBuffer output, boolean endOfInput) 方法的东西,它可以很好地控制写入输出,包括写入到给定限制和根据需要在输出缓冲区之间切换的能力。

从表面上看,这似乎可以使用 Cipher 的update(ByteBuffer input, ByteBuffer output)方法来实现,其中输入的限制已在调用之前设置,即。以避免超出输出缓冲区的容量。如果我正确理解 API 文档,Cipher 实现可能会在调用此方法之间缓冲任何数量的加密数据,因此可以想象,对 update() 或 doFinal() 的单个调用可能需要输出 ByteBuffer 的容量大于可从池中的固定大小缓冲区中获得。在这种情况下,根据这两种方法的文档:

如果 output.remaining() 字节不足以容纳结果,则会抛出 ShortBufferException。在这种情况下,使用更大的输出缓冲区重复此调用。使用 getOutputSize 确定输出缓冲区的大小。

有谁知道是否有办法解决这个问题?也许某种方式在 update() 调用之间刷新加密数据以防止过多的缓冲区积累......?我还没有走上尝试 CipherOutputStream 的道路。同样,关键目标是使用加密数据直接填充一系列固定大小的 ByteBuffer,而无需分配/填充中间字节数组。

4

2 回答 2

0

为了最终调查类似需求的任何人的利益:

我最终确实使用 Cipher 的update(ByteBuffer input, ByteBuffer output)方法来填充 ByteBuffer,但是它只使用一个输出缓冲区,而不是在一系列固定长度的缓冲区之间切换。正如文档所建议的那样(尽管我尽量避免使用此方法),调用 getOutputSize() 用于获取下一次 update() 调用的输出大小上限,并根据需要分配新缓冲区。

无论是否使用 CipherOutputStream 及其 flush() 方法,您可以对密码输出进行多少控制都是有限制的。这是有道理的:例如,如果将输入的前 15 个字节提交给 128 位(16 字节)分组密码(例如 AES),则输出将始终被保留,直到收到进一步的输入。刷新可能会阻止密码缓冲超过数据块大小,但如果你想使用它update(ByteBuffer input, ByteBuffer output)来巧妙地填充尽可能多的输出,然后为下一次调用保留剩余的输出,那么你就不走运了 -您需要提供自己的中间“溢出”缓冲区来帮助分配字节。这是可行的,但有点混乱。

于 2012-10-22T09:57:12.320 回答
0

如果数据是任意的,那为什么需要加密呢?只需生成一些随机数据并将其输入您的字节数组即可。为了加密安全,只需使用加密质量的 RNG,例如SecureRandom. 这可用于生成任意数量的字节,请参阅SecureRandom.nextBytes().

否则,我认为您已经提到了解决问题的方法:CipherOutputStream.

于 2012-10-14T16:01:38.547 回答