我编写了以下客户端 - 服务器对,以设置IPSec连接的非常简化版本(与密码相关)。EOFException:在Java客户端 - 服务器应用程序中引发java.io.EOFException
的问题是,在第二次调用的readObject(),即:
// Receive finished message from server
finishedMessage = (BigInteger) inputStream.readObject();
我得到一个java.io.EOFException.
应该说,这对多数奔跑的EOFException
被抛出,但在一些运行中,它运行完美无瑕?
我一直在调试几个小时,但无法找到错误。
如果有人可以看到这个错误,请让我知道 - 我将不胜感激!
错误消息:
[CLIENT]: Connected...
[CLIENT]: Common key = 33569
java.io.EOFException
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at IPSecClient.SetupSSLConnection(IPSecClient.java:68)
at IPSecClient.main(IPSecClient.java:116)
客户:
import java.math.BigInteger;
import java.net.*;
import java.util.ArrayList;
import java.util.Random;
import java.io.*;
public class IPSecClient {
private Socket socket;
private ObjectInputStream inputStream;
private ObjectOutputStream outputStream;
private IPSec gen;
private ArrayList<BigInteger[]> messages;
private BigInteger[] message;
private final int port, numBits;
private String address;
private Random rand;
private int fixedNumber;
private BigInteger fixedPrime, fixedBase, partialKeyClient,
partialKeyServer, commonKey, publicKeyServer, modulusServer;
public IPSecClient() {
rand = new Random();
numBits = 256;
fixedNumber = rand.nextInt(1000);
fixedPrime = new BigInteger("51803");
fixedBase = new BigInteger("3");
gen = new IPSec();
gen.KeyGen(numBits);
messages = new ArrayList<BigInteger[]>();
port = 5000;
address = "localhost";
}
public void SetupSSLConnection() {
try {
socket = new Socket(address, port);
outputStream = new ObjectOutputStream(socket.getOutputStream());
inputStream = new ObjectInputStream(socket.getInputStream());
System.out.println("[CLIENT]: Connected...");
// Send partial key and certificate (public key) to server
partialKeyClient = fixedBase.pow(fixedNumber).mod(fixedPrime);
message = new BigInteger[] {partialKeyClient, gen.PublicKey(), gen.Modulus()};
messages.add(message);
outputStream.writeObject(message);
outputStream.flush();
// Receive partial key and certificate from server
message = (BigInteger[]) inputStream.readObject();
messages.add(message);
partialKeyServer = message[0];
publicKeyServer = message[1];
modulusServer = message[2];
// Generate common key
commonKey = partialKeyServer.pow(fixedNumber).mod(fixedPrime);
System.out.println("[CLIENT]: Common key = " + commonKey.intValue());
// Send finished message
BigInteger accumulatedMessages = AccumulateMessages(messages).mod(gen.PublicKey());
BigInteger finishedMessage = gen.GenerateRSASignature(accumulatedMessages);
outputStream.writeObject(finishedMessage);
outputStream.flush();
// Receive finished message from server
finishedMessage = (BigInteger) inputStream.readObject();
// Verify finished message
boolean result = gen.VerifyRSASignature(AccumulateMessages(messages).mod(publicKeyServer), finishedMessage, publicKeyServer, modulusServer);
System.out.println("[CLIENT]: Verification of finished message " + (result ? "succeeded" : "failed"));
if (!result) {
System.out.println("[CLIENT]: SSL-connection could not be estasblished...");
CloseConnection(-1);
}
System.out.println("[CLIENT]: SSL-connection estasblished...");
CloseConnection(0);
} catch (SocketException se) {
se.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
private void CloseConnection(int exitCode) {
try {
socket.close();
outputStream.close();
inputStream.close();
System.exit(exitCode);
} catch (IOException e) {
e.printStackTrace();
}
}
private BigInteger AccumulateMessages(ArrayList<BigInteger[]> messages) {
BigInteger accumulator = new BigInteger("0");
for (BigInteger[] message : messages)
{
for (BigInteger part : message)
{
accumulator = accumulator.add(part);
}
}
return accumulator;
}
public static void main(String[] args) {
IPSecClient client = new IPSecClient();
client.SetupSSLConnection();
}
}
服务器:
import java.io.*;
import java.math.BigInteger;
import java.net.*;
import java.util.ArrayList;
import java.util.Random;
public class IPSecServer {
private ServerSocket serverSocket;
private Socket socket;
private ObjectInputStream inputStream;
private ObjectOutputStream outputStream;
private IPSec gen;
private ArrayList<BigInteger[]> messages;
private BigInteger[] message;
private final int port;
private Random rand;
private int fixedNumber;
private BigInteger fixedPrime, fixedBase, partialKeyClient,
partialKeyServer, commonKey, publicKeyClient, modulusClient;
public IPSecServer() {
rand = new Random();
fixedNumber = rand.nextInt(1000);
fixedPrime = new BigInteger("51803");
fixedBase = new BigInteger("3");
gen = new IPSec();
gen.KeyGen(2048);
messages = new ArrayList<BigInteger[]>();
port = 5000;
}
public void SetupSSLConnection() {
try {
serverSocket = new ServerSocket(port);
System.out.println("[SERVER]: Listening...");
socket = serverSocket.accept();
inputStream = new ObjectInputStream(socket.getInputStream());
outputStream = new ObjectOutputStream(socket.getOutputStream());
System.out.println("[SERVER]: Connected... " + "Port/IP: " + socket.getPort() + socket.getInetAddress());
// Receive partial key and certificate from client
message = (BigInteger[]) inputStream.readObject();
messages.add(message);
partialKeyClient = message[0];
publicKeyClient = message[1];
modulusClient = message[2];
// Send partial key and certificate to client
partialKeyServer = fixedBase.pow(fixedNumber).mod(fixedPrime);
message = new BigInteger[] {partialKeyServer, gen.PublicKey(), gen.Modulus()};
messages.add(message);
outputStream.writeObject(message);
outputStream.flush();
// Generate common key
commonKey = partialKeyClient.pow(fixedNumber).mod(fixedPrime);
System.out.println("[SERVER]: Common key = " + commonKey.intValue());
// Receive finished message from client
BigInteger finishedMessage = (BigInteger) inputStream.readObject();
messages.add(new BigInteger[] {finishedMessage});
// Verify finished message
boolean result = gen.VerifyRSASignature(AccumulateMessages(messages).mod(publicKeyClient), finishedMessage, publicKeyClient, modulusClient);
System.out.println("[SERVER]: Verification of finished message " + (result ? "succeeded" : "failed"));
if (!result) {
System.out.println("[SERVER]: SSL-connection could not be estasblished...");
CloseConnection(-1);
}
// Send finished message to client
BigInteger accumulatedMessages = AccumulateMessages(messages).mod(gen.PublicKey());
finishedMessage = gen.GenerateRSASignature(accumulatedMessages);
outputStream.writeObject(finishedMessage);
outputStream.flush();
System.out.println("[SERVER]: SSL-connection estasblished...");
CloseConnection(0);
} catch (SocketException se) {
System.exit(0);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
private void CloseConnection(int exitCode) {
try {
socket.close();
outputStream.close();
inputStream.close();
serverSocket.close();
System.exit(exitCode);
} catch (IOException e) {
e.printStackTrace();
}
}
private BigInteger AccumulateMessages(ArrayList<BigInteger[]> messages) {
BigInteger accumulator = new BigInteger("0");
for (BigInteger[] message : messages)
{
for (BigInteger part : message)
{
accumulator = accumulator.add(part);
}
}
return accumulator;
}
public static void main(String[] args) {
IPSecServer server = new IPSecServer();
server.SetupSSLConnection();
}
}
安全:
import java.math.BigInteger;
import java.util.Random;
import java.security.*;
public class IPSec {
private static final BigInteger one = new BigInteger("1");
// private key (n,d)
private BigInteger privateKey;
// public key (n,e)
private BigInteger publicKey = new BigInteger("3");
// modulus n
private BigInteger modulus;
public IPSec() {
}
// PUBLIC KEY
public BigInteger PublicKey() {
return publicKey;
}
public BigInteger Modulus() {
return modulus;
}
// KEY GENERATION
public void KeyGen(int keyLength) {
BigInteger p = BigInteger.probablePrime((int)Math.ceil(keyLength/2), new Random());
BigInteger q = BigInteger.probablePrime((int)Math.ceil(keyLength/2), new Random());
while (!(p.subtract(one)).gcd(publicKey).equals(one))
p = p.nextProbablePrime();
while (!(q.subtract(one)).gcd(publicKey).equals(one))
q = q.nextProbablePrime();
BigInteger phi = (p.subtract(one)).multiply(q.subtract(one));
modulus = p.multiply(q);
privateKey = publicKey.modInverse(phi);
}
// ENCRYPT
public BigInteger Encrypt(BigInteger message) {
return message.modPow(publicKey, modulus);
}
public static BigInteger Encrypt(BigInteger message, BigInteger publicKey, BigInteger modulus) {
return message.modPow(publicKey, modulus);
}
// DECRYPT
public BigInteger Decrypt(BigInteger message) {
return message.modPow(privateKey, modulus);
}
// SIGNATURE GENERATION
// Generate RSA-signatures for a message
public BigInteger GenerateRSASignature(BigInteger message) {
MessageDigest digest;
try {
digest = MessageDigest.getInstance("SHA-256");
return Decrypt(new BigInteger(1, digest.digest(message.toByteArray())).mod(Modulus()));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
System.exit(-1);
}
return message;
}
// Verify RSA-signatures for a message
public boolean VerifyRSASignature(BigInteger message, BigInteger signature) {
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
return (new BigInteger(1, digest.digest(message.toByteArray())).mod(Modulus())).equals(Encrypt(signature));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
System.exit(-1);
}
return false;
}
public boolean VerifyRSASignature(BigInteger message, BigInteger signature,
BigInteger publicKey, BigInteger modulus) {
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
return (new BigInteger(1, digest.digest(message.toByteArray())).mod(Modulus())).equals(Encrypt(signature, publicKey, modulus));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
System.exit(-1);
}
return false;
}
public static void main(String[] args) {
Testing();
}
// MISC
public void printKeys() {
String s = "";
s += "public = " + publicKey + "\n";
s += "private = " + privateKey + "\n";
s += "modulus = " + modulus;
System.out.println(s);
}
public static void Testing() {
IPSec gen = new IPSec();
gen.KeyGen(128);
BigInteger message = new BigInteger("329");
System.out.println("Verify: " + gen.VerifyRSASignature(message, gen.GenerateRSASignature(message)));
}
}
这看起来像是简单地击中了'InputStream'的末尾。但是,如果没有在您的问题中发布的意见,我们可能无法确切地诊断原因。 –
我已更新错误消息。 – Shuzheng
我们也需要看到你的_input_。 –