簡體   English   中英

在沒有DataOutputStream和Socket的情況下關閉CipherOutputStream

[英]Close CipherOutputStream without DataOutputStream & Socket

我正在與Cipher合作,在那里將連接保持在基礎socketdataoutputstream 現在,根據CipherOutputStream文檔,為了使最終塊離開加密器,我們需要調用close() 因此,將它與try-with-resource一起使用也會關閉基礎流,我不希望因為我需要它們進行進一步的操作。

那么,有沒有什么方法或實現可以幫助我在沒有數據dataoutputstreamsocket情況下關閉cipheroutputstream 我聽說FilterOutputStream但是我不知道如何使用它們。

我的代碼:

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());
            }
        }

    }


現在,由於cos被包裝在try-with-resource中,當while循環結束時,它將關閉流和底層的dos流,這些流進一步包裝了msock導致整個套接字關閉,而我剩余的代碼無用。

剩余的代碼:

    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!");
     }

我以某種方式設法通過@EJP建議自己解決問題,以通過update()doFinal()創建自己的Cipher對象。

碼:

//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