繁体   English   中英

EOFException:Java客户端-服务器应用程序中引发了java.io.EOFException

[英]EOFException: java.io.EOFException is thrown in Java client-server application

我已经对以下客户机/服务器对进行了编程,以设置非常简化的IPSec连接(与密码相关)。

问题是,在第二次调用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)));
    }
}

您的服务器在此处的签名验证阶段大吵大闹:

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

并关闭套接字,而不发送FINISHED消息。 检查其输出日志。 在这种情况下,也许您应该先发送一个错误对象。 否则将EOFException视为握手失败。

注意:

  • 为了安全起见,最好在两端的ObjectInputStream之前构造ObjectOutputStream
  • 您应该关闭ObjectOutputStream,而不是套接字或输入流。 这样,您可以确定它被冲洗了。 关闭这三个中的任何一个都会关闭其他两个。
  • 如果不是,请不要将其称为“ SSL”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM