How can I force a CipherOutputStream to finish encrypting but leave the underlying stream open?

假如想象 提交于 2019-12-06 23:43:01

问题


I have a CipherOutputStream backed by another OutputStream. After I have finished writing all the data I need encrypted to the CipherOutputStream, I need to append some unencrypted data.

The documentation for CipherOutputStream says that calling flush() will not force the final block out of the encryptor; for that I need to call close(). But close() also closes the underlying OutputStream, which I still need to write more to.

How can I force the last block out of the encryptor without closing the stream? Do I need to write my own NonClosingCipherOutputStream?


回答1:


If you don't have a reference to the Cipher, you could pass a FilterOutputStream to the method that creates the CipherOutputStream. In the FilterOutputStream, override the close method so that it doesn't actually close the stream.




回答2:


maybe you can wrap your outputstream before putting into an cipheroutputstream

/**
 * Represents an {@code OutputStream} that does not close the underlying output stream on a call to {@link #close()}.
 * This may be useful for encapsulating an {@code OutputStream} into other output streams that does not have to be
 * closed, while closing the outer streams or reader.
 */
public class NotClosingOutputStream extends OutputStream {

    /** The underlying output stream. */
    private final OutputStream out;

    /**
     * Creates a new output stream that does not close the given output stream on a call to {@link #close()}.
     * 
     * @param out
     *            the output stream
     */
    public NotClosingOutputStream(final OutputStream out) {
        this.out = out;
    }

    /*
     * DELEGATION TO OUTPUT STREAM
     */

    @Override
    public void close() throws IOException {
        // do nothing here, since we don't want to close the underlying input stream
    }

    @Override
    public void write(final int b) throws IOException {
        out.write(b);
    }

    @Override
    public void write(final byte[] b) throws IOException {
        out.write(b);
    }

    @Override
    public void write(final byte[] b, final int off, final int len) throws IOException {
        out.write(b, off, len);
    }

    @Override
    public void flush() throws IOException {
        out.flush();
    }
}

hope that helps




回答3:


If you have a reference to the Cipher object that the CipherOutputStream wraps, you should be able to do what CipherOutputStream.close() does:

Call Cipher.doFinal, then flush() the CiperOutputStream, and continue.



来源:https://stackoverflow.com/questions/5449103/how-can-i-force-a-cipheroutputstream-to-finish-encrypting-but-leave-the-underlyi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!