使用CipherOutputStream传输客户端/服务器文件

时间:2013-08-24 19:15:55

标签: java serversocket encryption

尝试编写客户端/服务器程序,客户端读取文本文件并使用CipherOutputStream将其发送到服务器sockect。 创建了预期的文本文件但是为空,我发现以下错误

  

读取长度-1

     

EOF:空

我有这种方法 encrypt()进行加密,然后发出数据

private static void encrypt(InputStream is, OutputStream os) {

    try {

        byte[] buf = new byte[1024];

//此流的字节首先被编码

        os = new CipherOutputStream(os, ecipher);

//读取明文并写出来加密

        int numRead = 0;

        while ((numRead = is.read(buf)) >= 0) {

            os.write(buf, 0, numRead);

        }

//关闭所有流

        os.close();

    } catch (IOException e) {

        System.out.println("I/O Error:" + e.getMessage());

    }

}

以下是客户端的大部分代码

public void actionPerformed(ActionEvent e) {

    //Handle open button action.
    if (e.getSource() == openButton) {
        int returnVal = fc.showOpenDialog(FileChooserDemo.this);

        if (returnVal == JFileChooser.APPROVE_OPTION) {
            try {
                SecretKey key = KeyGenerator.getInstance("DES").generateKey();

                AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);

                ecipher = Cipher.getInstance("DES/CBC/PKCS5Padding");

                dcipher = Cipher.getInstance("DES/CBC/PKCS5Padding");

                ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);

                dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);

                File file = fc.getSelectedFile();

                Socket s = null;
                s = new Socket("localhost", 6880);
                DataOutputStream output = new DataOutputStream(s.getOutputStream());


                encrypt(new FileInputStream(file), output);

                log.append("encrypted " + newline);

                log.append("Sent" + file.getName() + "." + newline);
            } catch (Exception ex) {
                Logger.getLogger(FileChooserDemo.class.getName()).log(Level.SEVERE, null, ex);
            }
        } else {
            log.append("Open command cancelled by user." + newline);
        }
        log.setCaretPosition(log.getDocument().getLength());

        //Handle save button action.
    } else if (e.getSource() == saveButton) {
        int returnVal = fc.showSaveDialog(FileChooserDemo.this);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File file = fc.getSelectedFile();
            //This is where a real application would save the file.
            log.append("Saving: " + file.getName() + "." + newline);
        } else {
            log.append("Save command cancelled by user." + newline);
        }
        log.setCaretPosition(log.getDocument().getLength());
    }
}

然后侦听服务器使用CipherInputStream读取数据,然后将其写入文本文件。 服务器包含以下

private static void decrypt(InputStream is, OutputStream os) {

    try {

        byte[] buf = new byte[1024];

//从流中读取的字节将被解密

        CipherInputStream cis = new CipherInputStream(is, dcipher);

//读取解密的字节并将明文写入

        int numRead = 0;

        while ((numRead = cis.read(buf)) >= 0) {

            os.write(buf, 0, numRead);

        }

//关闭所有流

        cis.close();

        is.close();

        os.close();

    } catch (IOException e) {

        System.out.println("I/O Error:" + e.getMessage());

    }

}

public void run() {
    try {

        SecretKey key = KeyGenerator.getInstance("DES").generateKey();

        AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);


        dcipher = Cipher.getInstance("DES/CBC/PKCS5Padding");

        dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);

        decrypt(input, new FileOutputStream("cleartext-reversed.txt"));

        FileWriter out = new FileWriter("test.txt");
        BufferedWriter bufWriter = new BufferedWriter(out);


        System.out.println("receive from : "
                + clientSocket.getInetAddress() + ":"
                + clientSocket.getPort());
        //Step 1 read length
        int nb = input.read();
        System.out.println("Read Length" + nb);

        String enctext = Character.toString(input.readChar());
        Integer.toString(nb);
        //Step 2 read byte

        String st = new String("see if it can write");
        bufWriter.append(enctext);
        bufWriter.close();


        //Step 1 send length
        output.writeInt(st.length());
        //Step 2 send length
        output.writeBytes(st); // UTF is a string encoding
        //  output.writeUTF(data);
    } catch (NoSuchPaddingException ex) {
        Logger.getLogger(Connection.class.getName()).log(Level.SEVERE, null, ex);
    } catch (InvalidKeyException ex) {
        Logger.getLogger(Connection.class.getName()).log(Level.SEVERE, null, ex);
    } catch (InvalidAlgorithmParameterException ex) {
        Logger.getLogger(Connection.class.getName()).log(Level.SEVERE, null, ex);
    } catch (NoSuchAlgorithmException ex) {
        Logger.getLogger(Connection.class.getName()).log(Level.SEVERE, null, ex);
    } catch (EOFException e) {
        System.out.println("EOF:" + e.getMessage());
    } catch (IOException e) {
        System.out.println("IO:" + e.getMessage());
    } finally {
        try {
            clientSocket.close();
        } catch (IOException e) {/*close failed*/

        }
    }
}

1 个答案:

答案 0 :(得分:1)

服务器执行以下操作:

decrypt(input, new FileOutputStream("cleartext-reversed.txt"));

从输入流中读取所有内容,对其进行解密,并将结果写入文本文件并关闭输入流。

然后,你正试图做

int nb = input.read();
...
input.readChar()

因此尝试从输入流中再次读取,刚刚完全读取并关闭。

注意:如果不是将异常隐藏在

之后,诊断会更容易
System.out.println("EOF:" + e.getMessage());
你做了

e.printStackTrace();

会告诉你它是什么异常,以及它发生在哪里。