⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chat.java

📁 Its about cryptography example. useful for chatting with some sort of security
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
Chat program
last update 14th September 2006
uses RSA to exchange an AES session key

things to do:
don't use PORT+1 for file transmission
file send/receive gauge
option for local addr/port
better handling of disconnects/errors
about box
*/
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.util.*;
import javax.swing.*;




public class chat extends Applet implements ActionListener, KeyListener, WindowListener
{
	/** frame to run the applet in if run from command line */
	static JFrame appletFrame;

	/** properties file */
	Properties props = new Properties();

	/** name of properties file */
	protected static final String PROP_FILENAME = "chat.properties";

	/** buttons */
	Button btnConnect, btnListen, btnDisconnect, btnSendFile, btnReceiveFile, btnGenerateRSAkey;

	/** text fields */
	TextField txtRemoteMachine, txtPort, txtMessage, txtTimeout, txtRSAkeyLength, txtAESKeyLength;

	/** main area showing details of conversation and any errors */
	TextArea txtConversation;

	/** socket to remote machine */
	Socket remoteSocket;

	/** thread that listens for incoming messages */
	listener incomingDataListener;

	/** input stream for receiving data from remote machine */
	BufferedInputStream in;

	/** output stream for sending data to remote machine */
	BufferedOutputStream out;

	/** encryption manager to handle all encryption/decryption */
	encryptionManager encMan = new encryptionManager(this);

	/** flag indicating whether we are connected or not */
	boolean connected;

	/** a file being transmitted to the remote machine */
	sendFile outFile;

	/** a file being received from the remote machine */
	receiveFile inFile;

	/** transfer buffer size to use when transmitting/receiving files */
	int BUFFER_SIZE = 65535;



	/** entry point if class is run as an application */
	public static void main(String args[])
	{
		// create the frame this applet will run in
		appletFrame = new JFrame("Crypto chat program");
		Applet myApplet = new chat();
		myApplet.init();
		myApplet.start();
		appletFrame.getContentPane().add(myApplet);
		appletFrame.setResizable(true);
		appletFrame.setSize(800,550);
		appletFrame.addWindowListener((WindowListener)myApplet);
		appletFrame.show();
	}


	/** adds a gui component to the grid */
	private void addToGrid(Panel p, Component c, int x, int y)
	{
		GridBagConstraints gridBagConstraints = new GridBagConstraints();
		gridBagConstraints.gridx = x;
		gridBagConstraints.gridy = y;
		gridBagConstraints.fill = GridBagConstraints.BOTH;
		gridBagConstraints.insets = new Insets(5, 2, 5, 2);
		gridBagConstraints.weightx = 1.0;
		gridBagConstraints.weighty = 1.0;
		p.add(c, gridBagConstraints);
	}


	/** adds a gui component to the grid */
	private void addToGrid(Panel p, Component c, int x, int y, int xWeight, int yWeight)
	{
		GridBagConstraints gridBagConstraints = new GridBagConstraints();
		gridBagConstraints.gridx = x;
		gridBagConstraints.gridy = y;
		gridBagConstraints.fill = GridBagConstraints.BOTH;
		gridBagConstraints.insets = new Insets(5, 0, 5, 0);
		gridBagConstraints.weightx = xWeight;
		gridBagConstraints.weighty = yWeight;
		p.add(c, gridBagConstraints);
	}


	/** applet initialisation */
	public void init()
	{
		setLayout(null);

		readPropertiesFile();

		setLayout(new GridBagLayout());

		createInputsPanel();
		createButtonsPanel();
		createMessagesPanel();
	}


	private void createInputsPanel()
	{
		Panel pnlInputs = new Panel();
		pnlInputs.setLayout(new GridBagLayout());
		GridBagConstraints gridBagConstraints = new GridBagConstraints();
		gridBagConstraints.gridx = 0;
		gridBagConstraints.gridy = 0;
		gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
		gridBagConstraints.insets = new Insets(2, 5, 5, 2);
		gridBagConstraints.weightx = 1.0;
		gridBagConstraints.weighty = 1.0;
		add(pnlInputs, gridBagConstraints);

		// label for remote machine name
		Label lblServerName = new Label("Remote machine");
		addToGrid(pnlInputs, lblServerName, 0, 0);

		// remote machine name
		txtRemoteMachine = new TextField((String)props.get("peerAddress"));
		addToGrid(pnlInputs, txtRemoteMachine, 1, 0);

		// label for port
		Label lblPort = new Label("Port");
		addToGrid(pnlInputs, lblPort, 2, 0);

		// port
		txtPort = new TextField((String)props.get("port"));
		addToGrid(pnlInputs, txtPort, 3, 0);

		// label for timeout
		Label lblTimeout = new Label("Timeout");
		addToGrid(pnlInputs, lblTimeout, 4, 0);

		// timeout
		txtTimeout = new TextField((String)props.get("timeout"));
		addToGrid(pnlInputs, txtTimeout, 5, 0);

		// label for RSA key length
		Label lblRSAkeyLength = new Label("RSA key length");
		addToGrid(pnlInputs, lblRSAkeyLength, 0, 1);

		// RSA key length
		txtRSAkeyLength = new TextField((String)props.get("RSAKeyLength"));
		addToGrid(pnlInputs, txtRSAkeyLength, 1, 1);

		// label for AES key length
		Label lblAESKeyLength = new Label("AES key length");
		addToGrid(pnlInputs, lblAESKeyLength, 2, 1);

		// AES key length
		txtAESKeyLength = new TextField((String)props.get("AESKeyLength"));
		addToGrid(pnlInputs, txtAESKeyLength, 3, 1);
	}


	private void createButtonsPanel()
	{
		Panel pnlButtons = new Panel();
		pnlButtons.setLayout(new GridBagLayout());
		GridBagConstraints gridBagConstraints = new GridBagConstraints();
		gridBagConstraints.gridx = 0;
		gridBagConstraints.gridy = 1;
		gridBagConstraints.fill = GridBagConstraints.BOTH;
		gridBagConstraints.insets = new Insets(5, 0, 5, 0);
		gridBagConstraints.weightx = 1.0;
		gridBagConstraints.weighty = 1.0;
		add(pnlButtons, gridBagConstraints);

		// button for connecting to remote machine
		btnConnect = new Button("Connect");
		btnConnect.addActionListener(this);
		addToGrid(pnlButtons, btnConnect, 0, 0);

		// button for listening for remote machine
		btnListen = new Button("Listen");
		btnListen.addActionListener(this);
		addToGrid(pnlButtons, btnListen, 1, 0);

		// button for disconnecting
		btnDisconnect = new Button("Disconnect");
		btnDisconnect.addActionListener(this);
		addToGrid(pnlButtons, btnDisconnect, 2, 0);

		// button for sending file
		btnSendFile = new Button("Send file");
		btnSendFile.addActionListener(this);
		addToGrid(pnlButtons, btnSendFile, 3, 0);

		// button for receiving file
		btnReceiveFile = new Button("Receive file");
		btnReceiveFile.addActionListener(this);
		addToGrid(pnlButtons, btnReceiveFile, 4, 0);

		// button to generate new RSA key
		btnGenerateRSAkey = new Button("Generate key");
		btnGenerateRSAkey.addActionListener(this);
		addToGrid(pnlButtons, btnGenerateRSAkey, 5, 0);
	}


	private void createMessagesPanel()
	{
		Panel pnlMessages = new Panel();
		pnlMessages.setLayout(new GridBagLayout());
		GridBagConstraints gridBagConstraints = new GridBagConstraints();
		gridBagConstraints.gridx = 0;
		gridBagConstraints.gridy = 2;
		gridBagConstraints.fill = GridBagConstraints.BOTH;
		gridBagConstraints.insets = new Insets(5, 0, 5, 0);
		gridBagConstraints.weightx = 1.0;
		gridBagConstraints.weighty = 5.0;
		add(pnlMessages, gridBagConstraints);

		Label lblMessage = new Label("Enter message to send & press <Return>");
		addToGrid(pnlMessages, lblMessage, 0, 0, 1, 1);

		// message to send to the remote machine
		txtMessage = new TextField();
		txtMessage.addKeyListener(this);
		addToGrid(pnlMessages, txtMessage, 0, 1, 1, 1);

		// all messages between both machines
		txtConversation = new TextArea(10,60);
		txtConversation.setEditable(false);
		addToGrid(pnlMessages, txtConversation, 0, 2, 1, 10);

		// set connected state
		setConnected(false);
	}


	/** reads the properties file */
	private void readPropertiesFile()
	{
		// look for one in current directory
		try
		{
			props.load(new FileInputStream(PROP_FILENAME));

			// get hidden properties
			BUFFER_SIZE = Integer.parseInt((String)props.get("bufferSize"));
			rsa.privateKey.PRIME_PROBABILITY = Integer.parseInt((String)props.get("primeProbability"));
		}
		catch (Exception e)
		{
			// never mind, this must be the first time the user has run the application
			// set all default properties
			props.put("port", "1701");
			props.put("peerAddress", "");
			props.put("RSAKeyLength", "1024");
			props.put("AESKeyLength", "256");
			props.put("timeout", "60");

			// hidden properties
			props.put("primeProbability", "100");
			props.put("bufferSize", String.valueOf(BUFFER_SIZE));
		}
	}


	/** window event handler */
	public void actionPerformed (ActionEvent anEvent)
	{
		// make connection
		if (anEvent.getSource() == btnConnect)
			connect();

		// listen for incoming connection
		if (anEvent.getSource() == btnListen)
			listen();

		// disconnect
		if (anEvent.getSource() == btnDisconnect)
			disconnect();

		// send file
		if (anEvent.getSource() == btnSendFile)
			sendFile();

		// receive file
		if (anEvent.getSource() == btnReceiveFile)
			receiveFile();

		// generate RSA key
		if (anEvent.getSource() == btnGenerateRSAkey)
			generateRSAkey();
	}


	/** connect to the remote machine */
	private void connect()
	{
		try
		{
			// inform user connection being attempted
			log("Attempting to contact " + txtRemoteMachine.getText());

			// open a socket to the server
			remoteSocket = new Socket(txtRemoteMachine.getText(), new Integer(txtPort.getText()).intValue());

			// inform user connection made
			log("Established connection with " + remoteSocket.getInetAddress().getHostName() + " (" + remoteSocket.getInetAddress().getHostAddress() + ")");

			// create the input/output streams
			initStreams(false);
		}
		catch(Exception e)
		{
			reportException("connect()", e);
		}
	}


	/** listen for incoming connection */
	private void listen()
	{
		// make sure we have generated a private key
		encMan.ensurePrivateKeyExists();

		try
		{
			// create a server socket
			ServerSocket listenSocket = new ServerSocket(new Integer(txtPort.getText()).intValue(), 1);
			try
			{
				// set timeout
				listenSocket.setSoTimeout(new Integer(txtTimeout.getText()).intValue() * 1000);

				// inform user we are listening for a connection
				log("Listening on port " + txtPort.getText().trim() + "...");

				// accept an incoming connection
				remoteSocket = listenSocket.accept();

				// inform user connection received
				log("Received connection from " + remoteSocket.getInetAddress().getHostName() + " (" + remoteSocket.getInetAddress().getHostAddress() + ")");

				// set remote machine textbox
				txtRemoteMachine.setText(remoteSocket.getInetAddress().getHostName());

				// create the input/output streams
				initStreams(true);
			}
			finally
			{
				// close the listener socket
				listenSocket.close();
			}
		}
		catch(Exception e)
		{
			reportException("listen()", e);
		}
	}


	/** creates the input & output streams on the socket */
	private void initStreams(boolean server) throws IOException, ClassNotFoundException, java.security.InvalidKeyException
	{
		in = new BufferedInputStream(remoteSocket.getInputStream());
		out = new BufferedOutputStream(remoteSocket.getOutputStream());

		// initialise the exchange of keys
		if (server)
		{
			// generate private key
			log("Transmitting public key");
			encMan.initialiseHandshaking(in, out);
			log("Public key transmission complete");
		}
		else
		{
			// set the size of the AES key & wait for the RSA key to arrive
			encMan.RijndaelKeySize = Integer.parseInt(txtAESKeyLength.getText());
			encMan.RijndaelKeySize = encMan.RijndaelKeySize - (encMan.RijndaelKeySize % 8); // ensure multiple of 8, discard any excess
			log("Receiving remote public key");
			encMan.waitForHandshaking(in, out);
			//log("Received remote public key of " + encMan.getRemotePublicKeyLength() + " bits");
		}

		// create a new listener
		incomingDataListener = new listener(this);
		incomingDataListener.setPriority(Thread.MIN_PRIORITY);
		incomingDataListener.start();

		// inform user connection closed
		log("** HANDSHAKING COMPLETED **");

		// set connected state
		setConnected(true);
	}


	/** transmit a message to the remote machine */
	private void transmitMsg()
	{
		// send the message
		sendString(txtMessage.getText());

		// display the line of text
		log("YOU: " + txtMessage.getText());

		// reset the message box
		txtMessage.setText("");
	}


	/** sends a line of text to the remote machine */
	protected void sendString(String s)
	{
		try
		{
			// encrypt the string using AES
			String cipherText = encMan.encryptWithRijndael(s);

			// transmit the encrypted text
			ObjectOutput outStream = new ObjectOutputStream(out);
			outStream.writeObject(cipherText);
			outStream.flush();
		}
		catch (IOException e)
		{
			reportException("Error sending text", e);
		}
	}


	/** reads a line of text from the remote machine */
	protected String readString()
	{
		String plainText = null;
		try
		{
			// read the encrypted text
			ObjectInputStream inStream = new ObjectInputStream(in);
			String cipherText = (String)inStream.readObject();

			// decrypt it using AES
			plainText = encMan.decryptWithRijndael(cipherText);
		}
		catch (Exception e)
		{
			reportException("Error reading text", e);
		}
		return plainText;
	}


	/** logs a message */
	public void log(String s)
	{
		txtConversation.append("\r\n" + s);
		// System.out.println(s);
	}


	/** disconnect from remote machine */
	private void disconnect()
	{
		// send a disconnect message to the remote machine
		sendString(listener.DISCONNECT);

		// kill the listening thread
		incomingDataListener.setState(listener.STOP);

		// the listener thread closes the streams so we don't need to do it here
	}


	/** closes the input & output streams */
	protected void closeStreams()
	{
		try
		{
			out.close();
			in.close();
			remoteSocket.close();
		}
		catch(Exception e)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -