为什么我的程序关闭而不打印堆栈跟踪或异常?

时间:2017-12-27 03:29:27

标签: java rsa inputstream outputstream

出于某种原因,当我加载我的程序时它立即关闭 - 加载顺序是RunServer.java> Main.java。它是一个加密的消息传递应用程序,只有当我尝试在客户端或服务器接收消息时解密消息时才会执行此操作。

我知道这是一个愚蠢的代码量,但我无法进一步压缩它,因为我似乎无法在6天之后在其他地方复制错误+试图让它在更小的模型上工作。任何帮助深表感谢。感谢。

编辑:好的,所以我发现它肯定与客户端类中的bigIntegerAsModPow变量有关。

编辑:它与客户端类方法中的调用有关 - “whileChatting()”。现在我得到一个NullPointerException,我不确定它来自哪里。

Main.java

    import javax.swing.JFrame;
    import java.math.BigInteger;

    public class Main {
        public static void main(String[] args) {
            assignValues();

            client();
        }
    // Methods for the Main class //

    // Method for giving values to each variable needed for the encryption algorithm //
    private static void assignValues() {
        RSAEncryption rsa = new RSAEncryption();
        // Prompts the user for their desired bit length of keys //
        rsa.setBitLengthDefault();
        // Sets the values of the two prime keys that will be used for our encryption //
        rsa.setPrimeP(rsa.getBitLength());
        rsa.setPrimeQ(rsa.getBitLength());
        // Sets the value of prime p totient //
        rsa.setPrimePTotient(rsa.getPrimeP());
        // Sets the value of prime q totient //
        rsa.setPrimeQTotient(rsa.getPrimeQ());
        // Sets the value of e //
        rsa.setE(); 
        // Sets the value of d //
        rsa.setD(rsa.getE(), rsa.getPrimeP(), rsa.getPrimeQ());     
        // Sets the value of pq //
        rsa.setPQ(rsa.getPrimeP(), rsa.getPrimeQ());    
    }

    // Method that connects to the server and launches a client JFrame //
    private static void client() {
        // Instantiates the Client class, with the local IP address (This should be changed when in actual use) //
        Client client = new Client("127.0.0.1");

        // Sets up the default close situation (Which is when the JFrame is closed by the user) //
        client.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // Starts the running of the Client class as a thread //
        client.startRunning();
    }
}

Server.java

import java.io.*;
import java.math.BigInteger;
import java.net.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

public class Server extends JFrame {
     private JTextField userText;
     private JTextArea chatWindow;
     private ObjectOutputStream output;
     private ObjectInputStream input;
     private ServerSocket server;
     private Socket connection;

// Constructor for the Server sub-class //
public Server() {
    // Sets the title of the window //
    setTitle("Samuels Encryption Server Service");

    // Generates a new JTextField //
    userText = new JTextField();

    // Sets the JTextField to be un-editable //
    userText.setEditable(false);

    // Adds an action listener //
    userText.addActionListener(new ActionListener(){
        // Detects if the action is performed //
        public void actionPerformed(ActionEvent event){
            // Sends message with the contents of the action command //
            sendMessage(event.getActionCommand());

            // Sets the text field to empty //
            userText.setText("");
        }
    });
    // Adds the userText and sets the border layout to north of the screen //
    add(userText, BorderLayout.NORTH);

    // A new JTextArea is now instantiated //
    chatWindow = new JTextArea();

    // Adds the new JScrollPane, using the chatWindow variable and setting the border layout to center of the screen //
    add(new JScrollPane(chatWindow));

//      Use this to gain the full dimensions of the users screen //
//      Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
//      int width = (int) screenSize.getWidth();
//      int height = (int) screenSize.getHeight();

    // Sets the size of the whole window //
    setSize(325,375);

    // Sets visibility of the Swing components to true //
    setVisible(true);
}

// Starts the Server class // 
public void startRunning() {
    BasicMethods bsc = new BasicMethods();
    try {
        // Instantiates the server with port '6789' and allows 100 users to queue //
        server = new ServerSocket(6789, 100);
        while(true) {
            try {
                // Waits for a user to connect //
                waitForConnection();

                // Sets up the i/o streams //
                setupStreams();

                // Sets up the GUI to read the input stream //
                whileChatting();
            } catch(EOFException eofException) {
                // If an EOFException is given to the program, then this message is shown //
                showMessage("\nThe server has ended the connection.");
            } finally {
                // Closes the streams and makes sure the text fields are un-editable //
                closeEverything();
            }
        }
    } catch(IOException ioException) {
        // If an IOException is given to the program, then the stack trace is printed to the console //
        ioException.printStackTrace();
    }
}

// Method that waits for a user to connect to the server //
private void waitForConnection() throws IOException {
    showMessage("Waiting for another user to connect...");
    // Accepts any connection that the server receives //
    connection = server.accept();
    showMessage("\nYou have connected to " + connection.getInetAddress().getHostName());
}

// Sets the streams up in preparation for data to be sent //
private void setupStreams() throws IOException {
    // Sets up the output stream //
    output = new ObjectOutputStream(connection.getOutputStream()); 

    // Flushes spare bytes out of the Client machine //
    output.flush();

    // Sets up the input stream //
    input = new ObjectInputStream(connection.getInputStream());

    showMessage("\nStreams are now setup!");
}

// Method that is run whilst the users are connected to each other //
private void whileChatting() throws IOException {
    String message = "You are now connected!\n";
    sendMessage(message);
    // Sets the chat box to be editable //
    ableToType(true);
    do {
        try {
            message = (String) input.readObject();
        //  RSAEncryption rsa = new RSAEncryption();

        //  BigInteger bigIntegerModPow = new BigInteger(message).modPow(rsa.getD(), rsa.getPQ());

            showMessage("\n" + new String(message));
        } catch(ClassNotFoundException classNotFoundException) {
            showMessage("\nThe server is unable to understand that String.");   
        }
    } while(!message.equals("Client : END CONNECTION"));
}

// Method that sends a message using the output stream //
private void sendMessage(String message) {
    try {
        if (message.length() < 1 || message.length() > 50) {

        } else {
            showMessage("\nServer : " + message);

            RSAEncryption rsa = new RSAEncryption();

            rsa.setPrimeP(1024);
            rsa.setPrimeQ(1024);

            BigInteger p = rsa.getPrimeP();
            BigInteger q = rsa.getPrimeQ();

            rsa.setE();
            rsa.setPQ(p, q);

            BigInteger e = rsa.getE();
            BigInteger pq = rsa.getPQ();

            byte[] messageAsBytes = message.getBytes();

            BigInteger bigIntegerModPow = new BigInteger(messageAsBytes).modPow(e, pq);

            output.writeObject("Server : " + bigIntegerModPow);
            // Flushes the output stream //
            output.flush();
        }
    } catch(IOException ioException) {
        // If an IOException is given to the program, then this message is printed to the console //
        chatWindow.append("\nERROR CODE : 0");

        ioException.printStackTrace();
    } 
}

// Method that does not allow the user to type to the text box and closes the i/o streams //
private void closeEverything() {
    showMessage("\nClosing connections...\n");
    // Sets the text box to be un-editable //
    ableToType(false);
    try {
        // Closes the output stream //
        output.close();

        // Closes the input stream //
        input.close();

        // Closes the connection between Client and Server //
        connection.close();
    } catch(IOException ioException) {
        // If an IOException is given to the program, then the stack trace is printed to the console //
        ioException.printStackTrace();
    }
}

// Method that prints a message to the text field //
private void showMessage(final String text) {
    // Invokes a new runnable //
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            // Appends the message to the chat window //
            chatWindow.append(text);
        }
    });
}

// Method that deals with permissions of the text field //
private void ableToType(final boolean tof) {
    SwingUtilities.invokeLater(new Runnable() {
        // Invokes a new runnable //
        public void run() {
            // Sets the userText field to be editable (depending on the input of the function //
            userText.setEditable(tof);
        }
    });
}
}

Client.java

import java.io.*;
import java.math.BigInteger;
import java.net.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

public class Client extends JFrame {
    private JTextField userText;
    private JTextArea chatWindow;
    private ObjectOutputStream output;
    private ObjectInputStream input;
    private String message = "";
    private String serverIP;
    private Socket connection;

// Constructor for the Client sub-class //
public Client(String host) {
    // Sets the title of the window //
    setTitle("Samuels Encryption Client Service");

    // Sets the IP address of the server to connect to //
    serverIP = host;

    // Generates a new JTextField //
    userText = new JTextField();

    // Sets the JTextField to be un-editable //
    userText.setEditable(false);

    // Adds an action listener //
    userText.addActionListener(new ActionListener() {

        // Detects if the action is performed //
        public void actionPerformed(ActionEvent event) {
            // Sends message with the contents of the action command //
            sendMessage(event.getActionCommand());

            // Sets the text field to empty //
            userText.setText("");
        } 
    });
    // Adds the userText and sets the border layout to north of the screen //
    add(userText, BorderLayout.NORTH);

    // A new JTextArea is now instantiated //
    chatWindow = new JTextArea();

    // Adds the new JScrollPane, using the chatWindow variable and setting the border layout to center of the screen //
    add(new JScrollPane(chatWindow), BorderLayout.CENTER);

//      Use this to gain the full dimensions of the users screen //     
//      Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
//      int width = (int) screenSize.getWidth();
//      int height = (int) screenSize.getHeight();

    // Sets the size of the whole window //
    setSize(325,375);

    // Sets visibility of the Swing components to true //
    setVisible(true);
}

// Starts the Client class //
public void startRunning() {
    try {
        // Connects to the server //
        connectToServer();

        // Sets up the i/o streams //
        setupStreams();

        // Sets up the GUI to read the input stream //
        whileChatting();
    } catch(EOFException eofException) {
        // If an EOFException is given to the program, then this message is shown //
        showMessage("\nClient terminated connection.");
    } catch(IOException ioException) {
        // If an IOException is given to the program, then the stack trace is printed to the console //
        ioException.printStackTrace();
    } finally {
        // Closes the streams and makes sure the text fields are un-editable //
        closeEverything();
    }
}

// Method that connects to the server using an IP and port //
private void connectToServer() throws IOException {
    showMessage("Attempting connection...");

    // Sets up the connection using the IP and port of the server machine //
    connection = new Socket(InetAddress.getByName(serverIP), 6789);

    showMessage("\nConnected to : " + connection.getInetAddress().getHostName());
}

// Sets the streams up in preparation for data to be sent //
private void setupStreams() throws IOException {
    // Sets up the output stream //
    output = new ObjectOutputStream(connection.getOutputStream());

    // Flushes spare bytes out of the Client machine //
    output.flush();

    // Sets up the input stream //
    input = new ObjectInputStream(connection.getInputStream());

    showMessage("\nYour streams are good to go.");
}

// Method that is run whilst the users are connected to each other //
private void whileChatting() throws IOException {
    // Sets the chat box to be editable //
    ableToType(true);
    do {
        try {
            // Casts the input.readObject to a String //
            message = (String) input.readObject();

            RSAEncryption rsa = new RSAEncryption();

            BigInteger d = rsa.getD();
            BigInteger pq = rsa.getPQ();

            byte[] messageAsByteValue = message.getBytes();

            byte[] bigIntegerModPowAsByteArray = new BigInteger(messageAsByteValue).modPow(d, pq).toByteArray();

            String finalString = bigIntegerModPowAsByteArray.toString();
            // Prints the input.readObject to the console //
            showMessage("\n" + finalString);
        } catch(ClassNotFoundException classNotFoundException) {
            showMessage("\nThe server is unable to understand that String.");
        }
    }
    while(!message.equals("Server : END CONNECTION"));
}

// Method that sends a message using the output stream //
private void sendMessage(String message) throws NullPointerException {
    try {
        if (message.length() < 1 || message.length() > 50) {

        } else {            
            showMessage("\nClient : " + message);

            RSAEncryption rsa = new RSAEncryption();

            rsa.setPrimeP(1024);
            rsa.setPrimeQ(1024);

            BigInteger p = rsa.getPrimeP();
            BigInteger q = rsa.getPrimeQ();

            rsa.setE();
            rsa.setPQ(p, q);

            BigInteger e = rsa.getE();
            BigInteger pq = rsa.getPQ();

            byte[] messageAsBytes = message.getBytes();

            BigInteger bigIntegerModPow = new BigInteger(messageAsBytes).modPow(e, pq);

            output.writeObject("Client : " + bigIntegerModPow);
            // Flushes the output stream //
            output.flush();
        }
    } catch(IOException ioException) {
        // If an IOException is given to the program, then this message is printed to the console //
        chatWindow.append("\nClient had an issue with sending that message.");
    }
}

// Method that does not allow the user to type to the text box and closes the i/o streams //
private void closeEverything() {
    showMessage("\nClosing all connections...");
    // Sets the text box to be un-editable //
    ableToType(false);
    try {
        // Closes the output stream //
        output.close();

        // Closes the input stream //
        input.close();

        // Closes the connection between Client and Server //
        connection.close();
    } catch(IOException ioException) {
        // If an IOException is given to the program, then the stack trace is printed to the console //
        ioException.printStackTrace();
    }
}

// Method that prints a message to the text field //
private void showMessage(final String message) {
    // Invokes a new runnable //
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            // Appends the message to the chat window //
            chatWindow.append(message);
        }
    });
}

// Method that deals with permissions of the text field //
private void ableToType(final boolean tof) {
    // Invokes a new runnable //
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            // Sets the userText field to be editable (depending on the input of the function //
            userText.setEditable(tof);
        }
    });
}
}

RSAEncryption.java

import java.math.BigInteger;
import javax.swing.JOptionPane;
import java.security.SecureRandom;

public class RSAEncryption { 
    private String userInput;
    private int bitLength;
    private BigInteger p;
    private BigInteger q;
    private BigInteger pq;
    private BigInteger pTotient;
    private BigInteger qTotient;
    private BigInteger e;
    private BigInteger d;

// This method sets the user input //
protected void setUserInput() {
    // Gets the message from the user //
    String userInput = "";
    while (userInput.length() < 1 || userInput.length() > 35) {
        userInput = JOptionPane.showInputDialog("Enter your message");
    }
    this.userInput = userInput;
}

// This method gets the user input //
protected String getUserInput() {
    return userInput;
}

// This method sets the bit length //
protected void setBitLength() {
    // Gets the bit length of the keys that the user wants to use //
    String userInputBitLengthString = JOptionPane.showInputDialog("Enter the bit length of the encryption keys (Binary Multiples)");
    // Parses the resulting String to an int //
    int userInputBitLengthInt = Integer.parseInt(userInputBitLengthString);

    this.bitLength = userInputBitLengthInt;
}

// This method sets the bit length to a default value //
protected void setBitLengthDefault() {
    this.bitLength = 1024;
}

// This method gets the bit length //
protected int getBitLength() {
    return bitLength;
}

// This method sets the value of prime p //
protected void setPrimeP(int bitLength) {
    SecureRandom random = new SecureRandom();
    BigInteger p = BigInteger.probablePrime(bitLength, random);
    this.p = p;
}

// This methods gets the value of prime p //
protected BigInteger getPrimeP() {
    return p;
}

// This method sets the value of prime q //
protected void setPrimeQ(int bitLength) {
    SecureRandom random = new SecureRandom();
    BigInteger q = BigInteger.probablePrime(bitLength, random);
    this.q = q;
}

// This method gets the value of prime q //
protected BigInteger getPrimeQ() {
    return q;
}

// This method calculates and sets the value of pq //
protected void setPQ(BigInteger p, BigInteger q) {
    this.pq = p.multiply(q);
}

// This method gets the value of pq //
protected BigInteger getPQ() {
    return pq;
}

// This sets the totient of prime p //
protected void setPrimePTotient(BigInteger p) {
    BigInteger one = new BigInteger("" + 1);
    BigInteger pTotient = p.subtract(one);
    this.pTotient = pTotient;
}

// This gets the totient of prime p //
protected BigInteger getPrimePTotient() {
    return pTotient;
}

// This sets the totient of prime q //
protected void setPrimeQTotient(BigInteger q) {
    BigInteger one = new BigInteger("" + 1);
    BigInteger qTotient = q.subtract(one);
    this.qTotient = qTotient;
}

// This gets the totient of prime q //
protected BigInteger getPrimeQTotient() {
    return qTotient;
}

// This sets the value of e //
protected void setE() {
    BigInteger e = new BigInteger("" + 65537);
    this.e = e;
}

// This gets the value of e //
protected BigInteger getE() {
    return e;
}

// This calculates and sets the value of d //
protected void setD(BigInteger e, BigInteger primeP, BigInteger primeQ) {
    BigInteger phi = p.subtract(BigInteger.ONE).multiply(q.subtract(BigInteger.ONE));
    BigInteger d = e.modInverse(phi);
    this.d = d;
}

// This gets the value of d //
protected BigInteger getD() {
    return d;
}

// This calculates the lowest common multiple of given values //
protected BigInteger lcm(BigInteger PrimePTotient, BigInteger PrimeQTotient) {
    return PrimePTotient.multiply(PrimeQTotient.divide(gcd(PrimePTotient, PrimeQTotient)));
}

// This calculates the greatest common divisor of given values //
protected BigInteger gcd(BigInteger a, BigInteger b) {
    BigInteger zero = new BigInteger("" + 0);
    while(!b.equals(zero)) {
        BigInteger temp = b;
        b = a.mod(b);
        a = temp;
    }
    return a;
}

// Method that encrypts the users message //
public byte[] returnEncryptedMessage(byte[] message, BigInteger p, BigInteger q, BigInteger e, BigInteger pq) {
    return (new BigInteger(message)).modPow(e, pq).toByteArray();
}

// Method that decrypts the users message //
public byte[] returnDecryptedMessage(byte[] message, BigInteger d, BigInteger pq) {
    return (new BigInteger(message)).modPow(d, pq).toByteArray();
}

// Method that converts byte array to a String //
public String bytesToString(byte[] encrypted) {
    String test = "";
    for (byte b : encrypted) {
        test += Byte.toString(b);
    }
    return test;
}

// This method casts an int to a BigInteger //
public BigInteger castBigInteger(int number) {
    BigInteger x = new BigInteger("" + number);
    return x;
}

// This method powers and modulos the given values //
public BigInteger powerMod(BigInteger message, BigInteger e, BigInteger pq) {
    BigInteger powerMod = message.modPow(e,
            pq);
    return powerMod; 
}
}

RunServer.java

import javax.swing.JFrame;

public class RunServer {
public static void main(String[] args) {
    Server server = new Server();
    server.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    server.startRunning();
}
}

BasicMethods.java

public class BasicMethods {
// Method to print to the console in white text // 
public void println(Object x) {
    System.out.println(x);
}

// Method to print to the console in red text //
public void errorPrintln(Object x) {
    System.err.println(x);
}

// Method to exit the program and return 0 // 
public void exit(int x) {
    System.exit(x);
}
}

1 个答案:

答案 0 :(得分:-1)

它可能与你对System.exit()的调用有关,它会杀死整个JVM - 从而破坏堆栈的内容。