UDP协议实现对等通讯Java+RSA加密解密传送信息实现

UDP协议实现对等通讯Java+RSA加密解密传送信息实现

RSA算法部分使用了:Java实现RSA加密解密算法 文章的代码

完整代码:UDP协议Java实现对等通讯

思路流程:




执行效果:



下面贴出客户端代码(RSA算法部分参照开头的说明链接,因为是对等通讯,所以服务端代码和客户端是一样的,只是他们的监听和发送端口互换而已):

package win1;

import java.awt.EventQueue;
import java.awt.Rectangle;
import java.awt.TextArea;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;

import java.awt.event.ActionEvent;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import myrsa2.RSAUtils;

public class ClientWindow1 extends JFrame implements Runnable
{

	/**
	 * 
	 */
	private static final long serialVersionUID = -9061845795224200533L;
	private JPanel contentPane;

	JLabel jLabel1 = new JLabel();
	TextArea jTextArea1 = new TextArea("你好!  ", 100, 250,TextArea.SCROLLBARS_VERTICAL_ONLY);
	JLabel jLabel2 = new JLabel();
	JTextField jTextField1 = new JTextField();
	Thread c;
	private DatagramSocket sendSocket, receiveSocket;
	private DatagramPacket sendPacket, receivePacket;

	//server端公钥参数
	private String public_exponent="65537";
	private String modulus="104344065049535235337602750745972062206029307981021347712560211453856339371441553987973583092897777954138410872748183586468653712704255491417965770505559379560464351555212396558781035059397673682011104226754831711072822991514780158821061675743098642785196847109412740308768227675829387795015925250708654667999";
	private RSAPublicKey pubKey;
	
	//client 端公钥密钥参数
	private String client_modulus="113073745494321136725643384276722554235918070888758423613996572688337880324241477133718433831999005142699224319183845232695295297468715990337671678419444783042160223540025404015195691927944232410884578134672967651594589403061833363946041818438441160271287476138927799777730705047831779398357394582752490728477";
	private String client_public_exponent="65537";
	private String client_private_exponent="96655390029103626966557334491451763291733925099701476254325068260270936930960095678899558748530086319165559082426693223382564625471030692505099487262702213820107182483208312048057602807578526587131082022149038938961334471000154642010315296540992797729318728885945908324955019647195175495375437240594636763713";
	private RSAPublicKey client_pubKey;
	private RSAPrivateKey client_priKey;  
	/**
	 * Launch the application.
	 */
	public static void main(String[] args)
	{
		EventQueue.invokeLater(new Runnable()
		{
			public void run()
			{
				try
				{
					ClientWindow1 frame = new ClientWindow1();
					frame.setVisible(true);
				} catch (Exception e)
				{
					e.printStackTrace();
				}
			}
		});
	}
	/*initial the pubkey and prikey 
	 */
	public void InitKey()
	{
		//使用模和指数生成公钥和私钥  
	    pubKey = RSAUtils.getPublicKey(modulus, public_exponent); 
	    jTextArea1.append("\nserver publicKey:" + pubKey);
	    client_pubKey = RSAUtils.getPublicKey(client_modulus, client_public_exponent); 
	    jTextArea1.append("\nclient publicKey:" + client_pubKey);
	    client_priKey= RSAUtils.getPrivateKey(client_modulus, client_private_exponent);	
	}
	
	/**
	 * Create the frame.
	 */
	public ClientWindow1()
	{
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 430, 500);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(null);

		//this.setSize(new Dimension(400, 400));
		this.setTitle("UDPClient");
		jLabel1.setText("通信记录:");
		jLabel1.setBounds(new Rectangle(10, 3, 70, 30));
		contentPane.setLayout(null);
		jTextArea1.setBounds(new Rectangle(15, 30, 400, 350));
		jTextArea1.setEditable(false);
		InitKey();
		jLabel2.setText("输入通信内容:");
		jLabel2.setBounds(new Rectangle(17, 385, 92, 37)); // 创建输入内容区域
		jTextField1.setText("");
		jTextField1.setBounds(new Rectangle(130, 385, 244, 31));
		jTextField1.setEditable(true);
		//监听输入框的回车事件
		jTextField1.addActionListener(new java.awt.event.ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				//执行,发送输入框信息
				jTextField1_actionPerformed(e);
			}
		});
		contentPane.add(jLabel1, null);
		contentPane.add(jTextArea1, null);
		contentPane.add(jTextField1, null);
		contentPane.add(jLabel2, null);
		try
		{
			sendSocket = new DatagramSocket();
			receiveSocket = new DatagramSocket(55512);
		} catch (SocketException e)
		{
			jTextArea1.append("不能打开数据报Socket,或者数据报Socket无法与指定端口连接!");
		}
		// 创建一个线程,监听本机55512端口,执行run();方法
		c = new Thread(this); 
		c.start();
	}
	protected void processWindowEvent(WindowEvent e) {
        super.processWindowEvent(e);
        if (e.getID() == WindowEvent.WINDOW_CLOSING) {
            System.exit(0);
        }
    }
	
	void jTextField1_actionPerformed(ActionEvent e)
	{
		try
		{
			Date date=new Date();
			DateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			String time=format.format(date);
			jTextArea1.append("\n\n客户端:"+time);
			String string1 = jTextField1.getText().trim();
			jTextArea1.append("\n加密前明文:"+string1);
			//加密后的密文  
			string1 = RSAUtils.encryptByPublicKey(string1, pubKey);
			jTextArea1.append("\n加密后密文:"+string1);
			//将信息发送到IP: 127.0.0.1 的55513端口
			sendPacket = new DatagramPacket(string1.getBytes(),
					string1.getBytes().length,
					java.net.InetAddress.getByName("127.0.0.1"), 55513);
			sendSocket.send(sendPacket);
		} catch (IOException ioe)
		{
			jTextArea1.append("\n网络通信出现错误,问题在于" + e.toString());
		} catch (Exception e1)
		{
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}

	@Override
	public void run()
	{
		// TODO Auto-generated method stub
		while (true)
		{
			try
			{
				byte buf[] = new byte[256];//接受的最大长度,超出的长度被丢弃
				receivePacket = new DatagramPacket(buf, buf.length);
				receiveSocket.receive(receivePacket);
				
				Date date=new Date();
				DateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				String time=format.format(date);
				jTextArea1.append("\n\n服务器:"+time);
				byte[] data = receivePacket.getData();
				String receiveString = new String(data);
				jTextArea1.append("\n解密前密文:"+receiveString);
				receiveString = RSAUtils.decryptByPrivateKey(receiveString, client_priKey); 
				jTextArea1.append("\n解密后密文:"+receiveString);
			} catch (IOException e)
			{
				jTextArea1.append("\n网络通信出现错误,问题在于" + e.toString());
			} catch (Exception e)
			{
				// TODO Auto-generated catch block
				jTextArea1.append("\nRSAUtils.decryptByPrivateKey error!!!:" + e.toString());
			}
		}
	}

}

                                                                                                                   感谢观看,欢迎指正!



先运行safechat包里的greetigserver.class,之后运行greetingclient.class即可。 如遇报错,请参考:https://blog.csdn.net/fengzun_yi/article/details/104497160 实现过程: 1. 采用TCP通信协议完成接收者发送者双方的消息传递。 2. 利用Diffie-Hellman密钥交换协议生成对称加密通信的通信密钥。 3. 为防止中间人攻击,采用RSA非对称加密算法协助DH算法完成密钥交换。具体过程如下: a. 接收者与发送者双方各自利用RSA算法生成自己的公私钥,并生成数字证书,并在一个CA进行认证。 b. 在DH密钥交换阶段,A生成A的DH协商密钥用于发送给B,该密钥与接收方私钥生成最终通信密钥。发送DH密钥时,A先用自己的私钥加密DH协商密钥,再去CA获得一个真实的B的公钥,用B的公钥对加密过的协商密钥再做一次加密,发送给B。(因为是用B的公钥加密过,只有B有B的私钥,所以接收信息只有B自己可以解密查看,又因为是用A的私钥加密过的,只有A有A的私钥,所以只有用A的公钥可以进行解密,所以可以保证协商密钥确实是A发送过来的,而且发送的信息也无法被中间人解密。)B收到信息之后,先用自己的私钥解密,然后去CA获得A的公钥再对消息解密一次,获得A的DH密钥。B发给A的过程同上。 c. 之后双方执行DH生成本地密钥的过程。A利用B发送过来的密钥和A的DH私钥生成通信密钥。B利用A发送过来的密钥和B的DH私钥生成通信密钥。根据DH原理,两者生成的通信密钥是相同的。 4. 利用上一步生成的通信密钥,采用AES对称加密算法进行加密通信。 为了方便起见,并没用对A和B双方进行颁发证书的操作,A的公钥默认B已经从CA获得,B的公钥默认A已经从CA获得。并且采用java控制台交互,仅仅为演示原理及简单效果。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值