client.java

来自「一个简单的实现Kerberos验证的程序」· Java 代码 · 共 627 行 · 第 1/2 页

JAVA
627
字号
/**
 * 客户端
 */
package src;

import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import java.security.*;
import javax.crypto.spec.*;
import javax.crypto.*;
import javax.swing.*;

public class Client extends JFrame{
	//GUI
	private JTextField usernamefield;
	private JPasswordField passwordfield;
	private JTextArea textArea;
	private JTextField messagefield;
	private JPanel panel1,panel2;
	private JButton connectButton ;
	private JButton sendButton;

	//
	String IDc,ADc,password;
	String IDtgs,IDs;
	long TS1,TS2,TS3,TS4,TS5;
	long Lifetime1,Lifetime2;
	Ticket_tgs Tickettgs;
	Ticket_s Tickets;
	Authenticator_tgs at;
	Authenticator_s as;
	byte[] subkey1;
	boolean pass;
	
	//socket变量
	Socket clientASSocket,clientTGSSocket,clientServerSocket;
	int port;
	ObjectOutputStream outstream,outstream2,outstream3;
	ObjectInputStream instream,instream2,instream3;
	
	//Key变量
	PrivateKey clientprikey;

	//加密解密辅助类实例
	Encryption en;
	
	public Client() throws Exception{
		//GUI
		super("SSKBS客户端");
		
		Container container = getContentPane();
		container.setLayout( new BorderLayout());
		
		panel1 = new JPanel();
		panel1.setLayout( new FlowLayout());
		container.add(panel1,BorderLayout.NORTH);
		
		JLabel usernameLabel = new JLabel("帐号:");
		panel1.add(usernameLabel);
		usernamefield = new JTextField(10);
		panel1.add(usernamefield);
		
		JLabel passwordLabel = new JLabel("密码:");
		panel1.add(passwordLabel);
		passwordfield = new JPasswordField(10);
		panel1.add(passwordfield);		
		
		connectButton = new JButton("连接");
		panel1.add(connectButton);
		connectButton.addActionListener(
				new ActionListener(){
					public void actionPerformed (ActionEvent event)
					{
						try{	
							IDc = usernamefield.getText();
							authentication();
						}
						catch(Exception ex)
						{
							ex.printStackTrace();
						}
					}
				}
		);
		
		textArea = new JTextArea(10,20);
		textArea.setEditable(false);
		container.add( new JScrollPane(textArea),BorderLayout.CENTER);
		
		panel2 = new JPanel();
		panel2.setLayout( new FlowLayout());
		container.add(panel2,BorderLayout.SOUTH);
		
		messagefield = new JTextField(20);
		panel2.add(messagefield);
		
		sendButton = new JButton("发送");
		sendButton.addActionListener(
				new ActionListener(){
					public void actionPerformed (ActionEvent event)
					{
						try{	
							if(pass){
								talkToServer("[From IP:"+ADc+"]->" +messagefield.getText());
							}
							else{
								JOptionPane.showMessageDialog(null,"还未登录验证,请先登录验证后再发送消息!","", JOptionPane.ERROR_MESSAGE);
							}
						}
						catch(Exception ex)
						{
							ex.printStackTrace();
						}
					}
				}
		);
		panel2.add(sendButton);
		
		
		setSize(400, 300);
		setVisible(true);
		
		
		en = new Encryption();
		ADc = InetAddress.getLocalHost().toString();
		
	}
	
	/**
	 * 初始化client端的socket方法
	 * port:所要连接的服务器的端口:5000--AS
	 */
	public void initClientASSocket(int port)
	{	
		this.port = port;
		try {
			clientASSocket = new Socket(InetAddress.getLocalHost(), port);
			//clientASSocket = new Socket(InetAddress.getByName("10.130.202.251"), port);
			outstream = new ObjectOutputStream(clientASSocket.getOutputStream());
			instream = new ObjectInputStream(clientASSocket.getInputStream());
			outstream.flush();
			textArea.append("与AS通信的socket初始化完毕...\n");
			System.out.println("与AS通信的socket初始化完毕");
		} 
		catch (Exception e) {
			e.printStackTrace();
		}
	}
	/**
	 * 初始化client端的socket方法
	 * port:所要连接的服务器的端口:6000--TGS
	 */
	public void initClientTGSSocket(int port){
		this.port = port;
		try {
			System.out.println(ADc+"*****"+port);
			clientTGSSocket = new Socket(InetAddress.getLocalHost(), port);
			//clientTGSSocket = new Socket(InetAddress.getByName("10.130.202.251"), port);
			outstream2 = new ObjectOutputStream(clientTGSSocket.getOutputStream());
			instream2 = new ObjectInputStream(clientTGSSocket.getInputStream());
			outstream2.flush();
			System.out.println("tgs socket init ok");
			textArea.append("与TGS通信的socket初始化完毕...\n");
		} 
		catch (Exception e) {
			e.printStackTrace();
		}
	}
	/**
	 * 初始化client端的socket方法
	 * port:所要连接的服务器的端口:7000--Server
	 */
	public void initClientServerSocket(int port){
		this.port = port;
		try {
			clientServerSocket = new Socket(InetAddress.getLocalHost(), port);
			//clientServerSocket = new Socket(InetAddress.getByName("10.130.202.251"), port);
			outstream3 = new ObjectOutputStream(clientServerSocket.getOutputStream());
			instream3 = new ObjectInputStream(clientServerSocket.getInputStream());
			outstream3.flush();
			System.out.println("service socket init ok");
			textArea.append("与Service Server通信的socket初始化完毕...\n");
		} 
		catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 加密解密部分
	 * AES加密方法
	 * @param plainText	明文
	 * @param k 密钥
	 * @return 密文
	 * @throws Exception
	 */
	public byte[] AESencrypt(byte[] plainText,Key k)throws Exception
	{	
		Cipher cipher=Cipher.getInstance("AES");
		cipher.init(Cipher.ENCRYPT_MODE,k);
		byte[] cipherText=cipher.doFinal(plainText);	
		return cipherText;	
	}
	
	/**
	 * 加密解密部分
	 * AES解密方法
	 * @param t	密文
	 * @param k 密钥
	 * @return 明文
	 * @throws Exception
	 */
	public String AESdecrypt(byte[] t,Key k)throws Exception
	{
		Cipher cipher=Cipher.getInstance("AES");	
		cipher.init(Cipher.DECRYPT_MODE,k);
		byte[] newPlainText = cipher.doFinal(t);	
		return new String(newPlainText,"UTF8");		
	}
	
	/**
	 * 对明文进行加密,这里都是用client的私钥加密,所以采用RSA非对称加密算法
	 * @param t	明文
	 * @param k client的私钥
	 * @return 密文
	 * @throws Exception
	 */
	public byte[] decrypt(byte[] t,Key k)throws Exception
	{
		Cipher cipher=Cipher.getInstance("RSA/ECB/PKCS1Padding");
		cipher.init(Cipher.DECRYPT_MODE,k);
		byte[] newPlainText = cipher.doFinal(t);
		System.out.println("用client的私钥解密完毕,client_privatekey:  "+new String(newPlainText,"UTF8"));
		textArea.append("用client的私钥解密完毕,client_privatekey:"+new String(newPlainText)+"...\n");
		return newPlainText;
	}
	//读取客户端密钥c_private.rsa
	public void getKeyFromFile()
	{
		try
		{
			System.out.println(System.getProperty("user.dir"));
			String file = "c_private.rsa";
			ObjectInputStream in = new ObjectInputStream(new FileInputStream(file));
			clientprikey = (PrivateKey)in.readObject();
			System.out.println(clientprikey);
			//textArea.append("用password解密完毕,已获得当前client的私钥"+clientprikey+"...\n");
			in.close();
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		
	}
	
	/**
	 * 生成一个时间戳。
	 * @return
	 */
	public long getTimeStamp()
	{	
		long now = System.currentTimeMillis();
		return now;
	}
	
	
	/**
	 * 判断当前会话是否在有效期内
	 * @param ts1
	 * @param ts2
	 * @param lifetime 有效期的长度
	 * @return true 有效 ;false 无效
	 */
	public boolean isInSession(long ts1,long ts2,long lifetime)
	{	
		if(ts1 + lifetime > ts2)
			return true;
		else return false;
	}
	
	/**
	 * 验证步骤
	 * 验证第一步,
	 * 向 Authenticator Server 认证
	 * 如果用户名未samantha则继续认证
	 * 如果不是则退出认证
	 */
	
	public boolean Step1(){
		textArea.append("开始向Authenticator Server发送认证请求...\n");
		try
		{
			/**
			 * (1)C->AS: IDc || ADc || TS1
			 */
			TS1 = getTimeStamp();
			C_AS c_as = new C_AS(IDc,ADc,TS1); 
			//Client->AS
			sendmessage(c_as,outstream);
			
			/**AS->Client
			 * (2)AS->C: 
			 * Tickettgs = Epub-tgs[Kpub-c || IDc || ADc || IDtgs || TS2 || Lifetime1] 
			 * Epub-c[IDtgs || TS2 || Lifttime1 || Tickettgs]
			 */
			while(true)
			{
				Object object = receivemessage(instream);
				//用户名不合法
				if(object!=null&&object instanceof String)
				{

⌨️ 快捷键说明

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