2015-05-12 16 views
0

我编写了以下客户端 - 服务器对,以设置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))); 
    } 
} 
+0

这看起来像是简单地击中了'InputStream'的末尾。但是,如果没有在您的问题中发布的意见,我们可能无法确切地诊断原因。 –

+0

我已更新错误消息。 – Shuzheng

+0

我们也需要看到你的_input_。 –

回答

1

您的服务器barfing在这里签名验证阶段:

if (!result) { 
    System.out.println("[SERVER]: SSL-connection could not be established..."); 
    CloseConnection(-1); 
} 

和关闭套接字不发送完成的消息。检查其输出日志。在这种情况下,你应该首先发送一个错误对象。否则将EOFException视为握手失败。

NB:

  • 为了安全起见,最好在ObjectInputStream两端之前去构造的ObjectOutputStream
  • 您应该关闭ObjectOutputStream,而不是套接字或输入流。这样你就可以确定它会被刷新。关闭其中三个关闭另外两个。
  • 不要在事件“SSL”时调用它们。
+0

我也应该关闭serverSocket,对不对? – Shuzheng

+0

不,为什么?让它循环接受另一个连接。一个协议失败并不意味着你应该停止整个服务器。特别是当你试图实现安全的东西。 – EJP

+0

Stll得到错误:-(,你试过运行代码吗? – Shuzheng

相关问题