【问题标题】:Client/Server file transfer using CipherOutputStream使用 CipherOutputStream 进行客户端/服务器文件传输
【发布时间】:2013-08-24 19:15:55
【问题描述】:

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

读取长度-1

EOF:null

我有这个方法 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);

//读入解密后的字节,将明文写入out

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

        }
    }
}

【问题讨论】:

    标签: java serversocket encryption


    【解决方案1】:

    服务器执行以下操作:

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

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

    然后,你就在尝试做

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

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

    注意:如果不是隐藏异常,诊断会容易得多

    System.out.println("EOF:" + e.getMessage());
    

    你做到了

    e.printStackTrace();
    

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

    【讨论】:

    • 感谢您的帮助,但我仍然无法使其正常工作。关于如何验证加密文本文件是否实际到达服务器的任何建议?在 decrypt() 调用之后,我已经取消了从流中读取的其他尝试,但我仍然留下一个空文本文件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 2016-12-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多