我们有一个包装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/

10-15 04:40