我们有一个包装BouncyCastle(实际上是Android的SpongyCastle)Blowfish的类,以加密要流式传输的数据:
public class BlowfishOutputStream extends OutputStream
{
private final OutputStream os;
private final PaddedBufferedBlockCipher bufferedCipher;
我们的原始代码在一次操作中将整个字节数组加密后再写入输出流
public void write(byte[] raw, int offset, int length) throws IOException
{
byte[] out = new byte[bufferedCipher.getOutputSize(length)];
int result = this.bufferedCipher.processBytes(raw, 0, length, out, 0);
if (result > 0)
{
this.os.write(out, 0, result);
}
}
发送图像(即一次发送大量数据)时,会导致两个副本立即保留在内存中。
以下代码是等效的,但不是等效的,我也不知道为什么。我可以验证是否正在发送数据(
c2
的总和等于length
),但是当我们在服务器上收到数据时,经过一个中间过程会丢弃该图像,然后再查看到达的内容。在此阶段,我所知道的是,当使用初始代码时,可以接收到响应,并且可以提取出包含的图像,当使用替换代码时,可以接收到(并接受)响应,但是图像似乎没有被提取。public void write(byte[] raw, int offset, int length) throws IOException
{
// write to the output stream as we encrypt, not all at once.
final byte[] inBuffer = new byte[Constants.ByteBufferSize];
final byte[] outBuffer = new byte[Constants.ByteBufferSize];
ByteArrayInputStream bis = new ByteArrayInputStream(raw);
// read into inBuffer, encrypt into outBuffer and write to output stream
for (int len; (len = bis.read(inBuffer)) != -1;)
{
int c2 = this.bufferedCipher.processBytes(inBuffer, 0, len, outBuffer, 0);
this.os.write(outBuffer, 0, c2);
}
}
请注意,此问题不是由于缺少对
doFinal
的调用而引起的,因为在关闭流时会调用该调用。public void close() throws IOException
{
byte[] out = new byte[bufferedCipher.getOutputSize(0)];
int result = this.bufferedCipher.doFinal(out, 0);
if (result > 0)
{
this.os.write(out, 0, result);
}
*nb try/catch omitted*
}
最佳答案
证实了,尽管具有讽刺意味的是,问题不在于图像,而在于先前的数据中,但该数据正在写入完整的raw
字节数组,而不仅仅是写入指定的范围。快速加密字节数组的等效代码为:
@Override
public void write(byte[] raw, int offset, int length) throws IOException
{
// write to the stream as we encrypt, not all at once.
final byte[] inBuffer = new byte[Constants.ByteBufferSize];
final byte[] outBuffer = new byte[Constants.ByteBufferSize];
int readStart = offset;
// read into inBuffer, encrypt into outBuffer and write to output stream
while(readStart<length)
{
int readAmount = Math.min(length-readStart, inBuffer.length);
System.arraycopy(raw, readStart, inBuffer, 0, readAmount);
readStart+=readAmount;
int c2 = this.bufferedCipher.processBytes(inBuffer, 0, readAmount, outBuffer, 0);
this.os.write(outBuffer, 0, c2);
}
}
关于java - 河豚代码应等效,但不应等效,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10220574/