我正在尝试根据请求将文件从服务器端发送到客户端。发送的文件是加密的,客户端shpuld对其进行解密。加密过程工作正常但在解密时我需要使用序列化的DerIOBuffer对象。我应该怎么做..请帮助
服务器:
import java.net.*;
import java.io.*;
import java.math.BigInteger;
import com.dragongate_technologies.borZoi.*;
public class FileServer {
static final int LISTENING_PORT = 3210;
public static void main(String[] args) {
File directory; // The directory from which the gets the files that it serves.
ServerSocket listener; // Listens for connection requests.
Socket connection; // A socket for communicating with a client.
/* Check that there is a command-line argument.
If not, print a usage message and end. */
if (args.length == 0) {
System.out.println("Usage: java FileServer <directory>");
return;
}
/* Get the directory name from the command line, and make
it into a file object. Check that the file exists and
is in fact a directory. */
directory = new File(args[0]);
if ( ! directory.exists() ) {
System.out.println("Specified directory does not exist.");
return;
}
if (! directory.isDirectory() ) {
System.out.println("The specified file is not a directory.");
return;
}
/* Listen for connection requests from clients. For
each connection, create a separate Thread of type
ConnectionHandler to process it. The ConnectionHandler
class is defined below. The server runs until the
program is terminated, for example by a CONTROL-C. */
try {
listener = new ServerSocket(LISTENING_PORT);
System.out.println("Listening on port " + LISTENING_PORT);
while (true) {
connection = listener.accept();
new ConnectionHandler(directory,connection);
}
}
catch (Exception e) {
System.out.println("Server shut down unexpectedly.");
System.out.println("Error: " + e);
return;
}
} // end main()
static class ConnectionHandler extends Thread {
// An object of this class is a thread that will
// process the connection with one client. The
// thread starts itself in the constructor.
File directory; // The directory from which files are served
Socket connection; // A connection to the client.
TextReader incoming; // For reading data from the client.
PrintWriter outgoing; // For transmitting data to the client.
ConnectionHandler(File dir, Socket conn) {
// Constructor. Record the connection and
// the directory and start the thread running.
directory = dir;
connection = conn;
start();
}
void sendIndex() throws Exception {
// This is called by the run() method in response
// to an "index" command. Send the list of files
// in the directory.
String[] fileList = directory.list();
for (int i = 0; i < fileList.length; i++)
outgoing.println(fileList[i]);
outgoing.flush();
outgoing.close();
if (outgoing.checkError())
throw new Exception("Error while transmitting data.");
}
void ecies_ex(String fileName) throws Exception {
// This function encrypts the file that has been requested
// by the client.
String at1,dc1,der1;
OutputStream os = connection.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(os);
ECDomainParameters dp = ECDomainParameters.NIST_B_163();
ECPrivKey skA = new ECPrivKey(dp, BigInteger.valueOf(123));
ECPubKey pkA = new ECPubKey(skA);
ECPrivKey skB = new ECPrivKey(dp, BigInteger.valueOf(230));
ECPubKey pkB = new ECPubKey(skB);
File file = new File(directory,fileName);
if ( (! file.exists()) || file.isDirectory()) {
// (Note: Don't try to send a directory, which
// shouldn't be there anyway.)
outgoing.println("error");
}
else {
outgoing.println("ok");
String pt1 = new String();
BufferedReader br = null;
try {
String sCurrentLine;
br = new BufferedReader(new FileReader(fileName));
while ((sCurrentLine = br.readLine()) != null) {
pt1=pt1+"\n"+sCurrentLine;
}
} catch (IOException e) {
e.printStackTrace();
}
ECIES crypt = new ECIES(skA, pkB, pt1.getBytes()); // encrypt the data
try {
DerIOBuffer der = new DerIOBuffer(crypt);
oos.writeObject(der);
ECIES decrypt = der.toECIES();
dc1=decrypt.toString2(); //cipher text
//at1=decrypt.toString3(); //authentication tag
FileWriter fstream = new FileWriter("encrypted.txt");
BufferedWriter out = new BufferedWriter(fstream);
out.write(dc1);
//Close the output stream
out.close();
} catch (Exception e) {
System.out.println(e.toString());
}
TextReader fileIn = new TextReader( new FileReader("encrypted.txt") );
while (fileIn.peek() != '\0') {
// Read and send lines from the file until
// an end-of-file is encountered.
String line = fileIn.getln();
outgoing.println(line);
}
}
outgoing.flush();
// oos.close();
// os.close();
outgoing.close();
if (outgoing.checkError())
throw new Exception("Error while transmitting data.");
}
public void run() {
// This is the method that is executed by the thread.
// It creates streams for communicating with the client,
// reads a command from the client, and carries out that
// command. The connection is logged to standard output.
// An output beginning with ERROR indicates that a network
// error occurred. A line beginning with OK means that
// there was no network error, but does not imply that the
// command from the client was a legal command.
String command = "Command not read";
try {
incoming = new TextReader( connection.getInputStream() );
outgoing = new PrintWriter( connection.getOutputStream() );
command = incoming.getln();
if (command.equals("index")) {
sendIndex();
}
else if (command.startsWith("get")){
String fileName = command.substring(3).trim();
ecies_ex(fileName);
//sendFile(fileName);
}
else {
outgoing.println("unknown command");
outgoing.flush();
}
System.out.println("OK " + connection.getInetAddress()
+ " " + command);
}
catch (Exception e) {
System.out.println("ERROR " + connection.getInetAddress()
+ " " + command + " " + e);
}
finally {
try {
connection.close();
}
catch (IOException e) {
}
}
}
} // end nested class ConnectionHandler
} //end class FileServer
客户:
import java.net.*;
import java.io.*;
import java.math.BigInteger;
import com.dragongate_technologies.borZoi.*;
public class FileClient {
static final int LISTENING_PORT = 3210;
public static void main(String[] args) {
String computer; // Name or IP address of server.
Socket connection; // A socket for communicating with that computer.
PrintWriter outgoing; // Stream for sending a command to the server.
TextReader incoming; // Stream for reading data from the connection.
String command; // Command to send to the server.
String pt3;
ECDomainParameters dp = ECDomainParameters.NIST_B_163();
ECPrivKey skB = new ECPrivKey(dp, BigInteger.valueOf(230));
//ECPrivKey skB = new ECPrivKey (dp);
ECPubKey pkB = new ECPubKey(skB);
/* Check that the number of command-line arguments is legal.
If not, print a usage message and end. */
if (args.length == 0 || args.length > 3) {
System.out.println("Usage: java FileClient <server>");
System.out.println(" or java FileClient <server> <file>");
System.out.println(" or java FileClient <server> <file> <local-file>");
return;
}
/* Get the server name and the message to send to the server. */
computer = args[0];
if (args.length == 1)
command = "index";
else
command = "get " + args[1];
/* Make the connection and open streams for communication.
Send the command to the server. If something fails
during this process, print an error message and end. */
try {
connection = new Socket( computer, LISTENING_PORT );
incoming = new TextReader( connection.getInputStream() );
outgoing = new PrintWriter( connection.getOutputStream() );
outgoing.println(command);
outgoing.flush();
}
catch (Exception e) {
System.out.println(
"Can't make connection to server at \"" + args[0] + "\".");
System.out.println("Error: " + e);
return;
}
/* Read and process the server's response to the command. */
try {
if (args.length == 1) {
// The command was "index". Read and display lines
// from the server until the end-of-stream is reached.
System.out.println("File list from server:");
while (incoming.eof() == false) {
String line = incoming.getln();
System.out.println(" " + line);
}
}
else {
// The command was "get <file-name>". Read the server's
// response message. If the message is "ok", get the file.
String message = incoming.getln();
if (! message.equals("ok")) {
System.out.println("File not found on server.");
return;
}
PrintWriter fileOut; // For writing the received data to a file.
if (args.length == 3) {
// Use the third parameter as a file name.
fileOut = new PrintWriter( new FileWriter(args[2]) );
}
else {
// Use the second parameter as a file name,
// but don't replace an existing file.
File file = new File(args[1]);
if (file.exists()) {
System.out.println("A file with that name already exists.");
System.out.println("To replace it, use the three-argument");
System.out.println("version of the command.");
return;
}
fileOut = new PrintWriter( new FileWriter(args[1]) );
}
while (incoming.peek() != '\0') {
// Copy lines from incoming to the file until
// the end of the incoming stream is encountered.
String line = incoming.getln();
fileOut.println(line);
}
InputStream is = connection.getInputStream();
ObjectInputStream ois = new ObjectInputStream(is);
DerIOBuffer der = (DerIOBuffer)ois.readObject();
ECIES decrypt = der.toECIES();
byte[] pt2 = decrypt.decrypt(skB); // decrypt the data
pt3=new String(pt2);
if (fileOut.checkError()) {
System.out.println("Some error occurred while writing the file.");
System.out.println("Output file might be empty or incomplete.");
}
}
}
catch (Exception e) {
System.out.println("Sorry, an error occurred while reading data from the server.");
System.out.println("Error: " + e);
}
} // end main()
} //end class FileClient
答案 0 :(得分:1)
如果您关心错误,则不应使用PrintWriter
。为什么?因为如果通过PrintWriter
在输出上发生错误,则无法找出它是什么。这使得很难弄清楚在这种情况下真正的问题是什么。我建议您修复此问题,以便找到问题的真正原因。
真正的问题可能与以下问题有关:
如果您尝试编写的内容可能是二进制文件,则根本不应使用PrintWriter
...或读者/作者。
您似乎不必要地使用了对象序列化......并且在类似于它可能无法序列化的类上。
基于我在寻找“borZoi”图书馆的文档时遇到的困难......以及其他一些事情......我认为你可能选择了一个较差的库进行加密工作。