last block incomplete with CipherInputStream/CipherOutputStream, even with padding AES/CBC/PKCS5Padding

后端 未结 6 2134
自闭症患者
自闭症患者 2020-12-28 18:06

Actually, I searched lot from internet and in stackoverflow too for this,

Initially I don\'t used padding in my encryption and decryption,

But Finally I got

6条回答
  •  醉话见心
    2020-12-28 18:49

    I've had exactly the same problem. The accepted solution works because you've used cipher mode that does not require padding, but this is not a way crypto-related issues are fixed.

    According to the CipherOutputStream documentation, you have to call close() method in order to finalize encryption properly (i.e., padding block is added).

    This method invokes the doFinal method of the encapsulated cipher object, which causes any bytes buffered by the encapsulated cipher to be processed. The result is written out by calling the flush method of this output stream.

    This method resets the encapsulated cipher object to its initial state and calls the close method of the underlying output stream.

    If you want to preserve OutputStream open even after calling CipherOutputStream.close() method, you can wrap OutputStream to the stream that does not close it. For example:

    public class NotClosingOutputStream extends OutputStream {
      private final OutputStream os;
    
      public NotClosingOutputStream(OutputStream os) {
        this.os = os;
      }
    
      @Override
      public void write(int b) throws IOException {
        os.write(b);
      }
    
      @Override
      public void close() throws IOException {
        // not closing the stream.
      }
    
      @Override
      public void flush() throws IOException {
        os.flush();
      }
    
      @Override
      public void write(byte[] buffer, int offset, int count) throws IOException {
        os.write(buffer, offset, count);
      }
    
      @Override
      public void write(byte[] buffer) throws IOException {
        os.write(buffer);
      }
    }
    

    Then you can use:

    ...
    cos = new CipherOutputStream(new NotClosingOutputStream(os), encipher);
    copyByte(is, cos);
    cos.close();
    ...
    

    Note the os stream does not get closed, you need to do it on your own when appropriate.

提交回复
热议问题