简体   繁体   English

在没有DataOutputStream和Socket的情况下关闭CipherOutputStream

[英]Close CipherOutputStream without DataOutputStream & Socket

I'm working with Cipher where connection is being held on the underlying socket and dataoutputstream . 我正在与Cipher合作,在那里将连接保持在基础socketdataoutputstream Now according to CipherOutputStream documentation, that in order to let the final block out of the encryptor, we need to call close() . 现在,根据CipherOutputStream文档,为了使最终块离开加密器,我们需要调用close() So using it with try-with-resource also closes the underlying stream which I don't want cuz I need them for further operations. 因此,将它与try-with-resource一起使用也会关闭基础流,我不希望因为我需要它们进行进一步的操作。

So is there any method or implementation which will help me in closing the cipheroutputstream without dataoutputstream and socket .? 那么,有没有什么方法或实现可以帮助我在没有数据dataoutputstreamsocket情况下关闭cipheroutputstream I heard about FilterOutputStream but I don't have any idea how to work with them. 我听说FilterOutputStream但是我不知道如何使用它们。

My Code: 我的代码:

public class ClientHandler implements Runnable {
Socket msock;
DataInputStream dis;
DataOutputStream dos;
String ip;
private miniClientHandler(Socket msock) {
            this.msock = msock;
        }
@Override
public void run() {
    try {
        dis = new DataInputStream(msock.getInputStream());
        dos = new DataOutputStream(msock.getOutputStream());

        ip = msock.getInetAddress().getHostAddress();

        String msg = dis.readLine();
        System.out.println(msg);

        if (msg.equals("Download")) {

                    String file2dl = dis.readLine(); //2
                    File file = new File(sharedDirectory.toString() + "\\" + file2dl);
                    dos.writeLong(file.length()); //3+

                    //AES-128 bit key initialization.
                    byte[] keyvalue = "AES128BitPasswd".getBytes();
                    SecretKey key = new SecretKeySpec(keyvalue, "AES");

                    //Initialize the Cipher.
                    Cipher encCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
                    encCipher.init(Cipher.ENCRYPT_MODE, key);

                    //Get the IV from cipher.
                    IvParameterSpec spec = null;
                    try {
                        spec = encCipher.getParameters().getParameterSpec(IvParameterSpec.class);
                    } catch (InvalidParameterSpecException ex) {
                        Logger.getLogger(PeersController.class.getName()).log(Level.SEVERE, null, ex);
                    }

                    byte[] iv = spec.getIV();

                    dos.write(iv, 0, iv.length); //4+

                    //Encryption Mechanism.
                    try (FileInputStream fis = new FileInputStream(file)) {
                        try (CipherOutputStream cos = new CipherOutputStream(dos, encCipher)) {
                            int read;
                            byte[] buffer = new byte[1024 * 1024];
                            while ((read = fis.read(buffer)) != -1) {
                                cos.write(buffer, 0, read); //5+ due to dos as underlying parameter of cos.
                            }
                        }
                    }

                    String message = dis.readLine();
                    System.out.println(message);
                    if (message.equals("Fetching Done")) {
                        System.out.println("Fetching Done!");
                    } else if (message.equals("Fetching Drop")) {
                        System.out.println("Fetching Denied!");
                    }
                }
            } catch (IOException | NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException e) {
                System.out.println(e.getMessage());
            }
        }

    }


Now since cos is wrapped in try-with-resource, when the while loop ends, it closes the stream and the underlying dos stream which have further wrapped msock resulting the whole socket to close and my remaining code left useless. 现在,由于cos被包装在try-with-resource中,当while循环结束时,它将关闭流和底层的dos流,这些流进一步包装了msock导致整个套接字关闭,而我剩余的代码无用。

Leftover code: 剩余的代码:

    String message = dis.readLine();
    System.out.println(message);
    if (message.equals("Fetching Done")) {
        System.out.println("Fetching Done!");
     } else if (message.equals("Fetching Drop")) {
                 System.out.println("Fetching Denied!");
     }

I somehow manage to solve my problem myself with the help of @EJP recommendation to create my own Cipher object via update() & doFinal() . 我以某种方式设法通过@EJP建议自己解决问题,以通过update()doFinal()创建自己的Cipher对象。

Code: 码:

//Encryption Mechanism.
  try (FileInputStream fis = new FileInputStream(file)) {

       byte[] buffer = new byte[1024 * 1024];
       byte[] cipherBlock = new byte[encCipher.getOutputSize(buffer.length)];
       int cipherBytes;
       int read;
       while ((read = fis.read(buffer)) != -1) {
              cipherBytes = encCipher.update(buffer, 0, read, cipherBlock);
              dos.write(cipherBlock, 0, cipherBytes);
        }
        cipherBytes = encCipher.doFinal(cipherBlock, 0); //let out the last block out of the encryptor.
        dos.write(cipherBlock, 0, cipherBytes);
     } catch (ShortBufferException | IllegalBlockSizeException | BadPaddingException ex) {
              Logger.getLogger(PeersController.class.getName()).log(Level.SEVERE, null, ex);
       }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM