JAVA realizes symmetric encryption AES algorithm encryption, and encrypts UDP communication

1-1 Assuming that Tom and Jerry use Java UDP to chat, please write a program for them. The details are as follows:
(1) Both Tom and Jerry chatting should have a sender and a receiver;
(2) Use DatagramSocket and DatagramPacket;
(3) Implement the java.lang.Runnable class and override the run() method.
(4) Tom uses a symmetric/asymmetric encryption algorithm (keys can be assigned independently and does not need to be distributed by an authority) to encrypt the content sent (the content sent is the student’s own name + the student’s student ID), and then Send the encrypted ciphertext to Jerry; Jerry decrypts the received ciphertext and restores it into plaintext content (ie the student’s name + student’s student ID)

In the death experiment, it took a long time to produce a symmetric encryption. Pure novices, there may be many mistakes, I hope the big guys point out in the comment area in time!
First of all, about the concept of AES algorithm and symmetric encryption, I won't go into details here. For details, please refer to the blog of this big guy. https://www.cnblogs.com/wushaopei/p/11979154.html

Environment configuration

First, download the Apache Commons Codec jar package, and download the bin file at the following address.
http://commons.apache.org/proper/commons-codec/download_codec.cgi
and then imported into Eclipse, I am reporting an error after importing here, pay attention to import the jar package of codc into the classpath.
Configuration as shown below
Insert picture description here

Next concrete realization

AES algorithm encryption

I used an AES class to implement the process of key generation, key acquisition, encryption and decryption.
The biggest problem encountered in the implementation process is how to send the generated key to the receiving thread after the sending thread randomly generates the key.
In the process of reading other people's blogs, I found that many bigwigs used to pass in an initial seed while initializing. Logically speaking, if the initial value passed in is the same, the generated key should be the same.
Insert picture description here

However, the actual operation was not successful. This line of the decrypted code will always report a Given final block not properly paddedInsert picture description here
error. The reason for the error should be that the generated key is different. However, the specific reason is not clear, so it can only Another way, I choose to save the generated key into a pkey.txt file, and read it directly when decrypting it.

The AES class code is as follows:

package Chat_UDP;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.Key;
import java.security.NoSuchAlgorithmException;

//import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;

//import org.bouncycastle.util.encoders.Base64;

public class AES {
    
    
	static String string = "杨丽冰 201831064402";
	//key
    KeyGenerator keyGenerator;
    //密钥对象
    SecretKey secretKey;
    //密钥
    byte[] keyBytes;
   //key
    Key key;
    
    //生成密钥
	public Key AESInit() throws NoSuchAlgorithmException, IOException {
    
    
		 //生成key
        KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
        //设置密钥长度
        keyGenerator.init(128);
        //生成密钥对象
        SecretKey secretKey = keyGenerator.generateKey();
        //获取密钥
        byte[] keyBytes = secretKey.getEncoded();
        //key转换
        key = new SecretKeySpec(keyBytes,"AES");
        //将密钥存入文件pkey.txt
        File file=new File("pkey.txt");
	    OutputStream outputStream=new FileOutputStream(file);
		outputStream.write(keyBytes);
		outputStream.close();
		return key;
	}
	
	//得到密钥
	public Key getKey() throws NoSuchAlgorithmException, IOException {
    
    
		//从文件中取出密钥
       	File file=new File("pkey.txt");
       	InputStream inputStream = new FileInputStream(file);
       	keyBytes = inputStream.readAllBytes();
       	key = new SecretKeySpec(keyBytes,"AES");
		return key;
	}
	
	public String encryptAES(byte[] s,Key key){
    
    
		byte[] result = null;
        try {
    
    
            //加密
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            //初始化,设置为加密
            cipher.init(Cipher.ENCRYPT_MODE, key);
            result = cipher.doFinal(s);
            System.out.println("AES对称算法加密后的密文为: " + Base64.encodeBase64String(result)); 
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }  
		return Base64.encodeBase64String(result);
    }
	
	public  String decryptAES(byte[] s,Key key){
    
    
		byte[] result = null;
        try {
    
    
            //加密
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            //初始化,设置为解密 
            cipher.init(Cipher.DECRYPT_MODE, key);
            result = cipher.doFinal(s);
            System.out.println("AES对称算法解密后的明文为:" + new String(result));
            
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
        return new String(result);
	}
}

Through the following code Test, we can test the encryption and decryption function of AES, and we can see that JAVA has been successfully implemented to encrypt with symmetric encryption AES algorithm, and then just write the encryption and decryption into the process of UDP communication.
Insert picture description here
Test class Test.java

package Chat_UDP;

import java.io.IOException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;

import org.apache.commons.codec.binary.Base64;

public class Test {
    
    
	public static void main(String []args) throws NoSuchAlgorithmException, IOException {
    
    
		AES aes = new AES();
		Key key = aes.AESInit();
		Key key1 = aes.getKey();
		if(key.equals(key1))
			System.out.println("YES!密钥一致!" ); 
		String s ="201831064402 杨丽冰";
		String result = null;
		//加密
		result = aes.encryptAES(s.getBytes(), key);
		//解密
		s= aes.decryptAES(Base64.decodeBase64(result),key1 );
	}
}

Encrypt UDP communication

Next, you only need to call the AES method to encrypt the data, initialize the key on the server or client, encrypt the data in the sending thread, and then send the ciphertext, and then decrypt the ciphertext into plaintext in the receiving thread. .

发送线程

```java
package Chat_UDP;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.util.Scanner;


public class Send_Thread extends Thread{
    
    
    //发送的socket端
    private DatagramSocket sender = null;
    //待发送的目标地址
    private InetSocketAddress address = null;
    //从键盘输入
    Scanner scan = new Scanner(System.in);
    public Send_Thread(DatagramSocket sender,InetSocketAddress address)
    {
    
    
        this.sender = sender;
        this.address = address;
    }
    
    @Override
    public void run() {
    
    
        // TODO Auto-generated method stub
        try
        {
    
    
            while(true)
            {
    
    
                //输入待发送的内容
                String input = scan.nextLine();
                if(input.equals("exit"))
                    break;
                AES aes = new AES();
        	    Key key = aes.getKey();
        		System.out.println("生成的密钥key是" + key); 
        		//对输入数据进行加密
        		input=aes.encryptAES(input.getBytes(), key);
                byte[] data = input.getBytes();
                data = input.getBytes("UTF-8");
                //创建UDP数据报,发送的是加密后的信息
                DatagramPacket pack = new DatagramPacket(data, data.length,address);
                sender.send(pack);    
            }
            System.out.println("Exit!");
            
        }catch(IOException | NoSuchAlgorithmException e)
        {
    
    
            System.out.println("IOException");
        }
    }
}

Receiving thread

package Chat_UDP;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Date;

import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;

public class Receive_Thread extends Thread {
    
    
    private static final int MAX_RECEIVE_BUFFER = 1024;
    private DatagramSocket server;
    private DatagramPacket packet;
    byte[] buffer = new byte[MAX_RECEIVE_BUFFER];
    
    public Receive_Thread(DatagramSocket server)
    {
    
    
        this.server = server;
        packet = new DatagramPacket(buffer, buffer.length);
    }
    
    @Override
    public void run() {
    
    
        try
        {
    
    
            while(true)
            {
    
    
                //接收数据包
                server.receive(packet);
                AES aes = new AES();
        		Key key = aes.getKey();
        		System.out.println("密钥key是" + key); 
        		String s = new String(packet.getData(),packet.getOffset(),packet.getLength(),"UTF-8");
        		System.out.println("接收到的信息为: " + s);
        		//对接收的数据解密
        		s = aes.decryptAES(Base64.decodeBase64(s), key);
                Date day=new Date();    
                SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");   
                if(packet.getPort() == 10001)
                	System.out.println("Tom"+packet.getAddress()+"  说:"+s+"\t"+df.format(day));
                else{
    
    
                	System.out.println("Jerry"+packet.getAddress()+" 说 :"+s+"\t"+df.format(day));
                }
                packet.setLength(buffer.length);
            }
        }
        catch(IOException | NoSuchAlgorithmException e)
        {
    
    
            System.out.println("IOException");
        }
    }
}

Server (TOM)

package Chat_UDP;
//杨丽冰 201831064402
import java.net.DatagramSocket;
import java.net.InetSocketAddress;

public class Chat_Server {
    
    
	//Tom
    private static final int DEST_PORT = 8888;
    private static final int SEND_PORT = 10001;
    private static final int RECE_PORT = 9000;
    private static final String IP = "127.0.0.1";

    public static void main(String[] args)
    {
    
    
        try{
    
    
        	System.out.println("TOM");
            Send_Thread send_thread = null;
            Receive_Thread rece_thread = null;
            InetSocketAddress address = null;
            //生成密钥
            AES aes = new AES();
            aes.AESInit();
            //创建待接受数据包的目的机的端口号和IP地址
            address = new InetSocketAddress(IP, DEST_PORT);
            //创建发送的Socket端
            DatagramSocket sendsocket = new DatagramSocket(SEND_PORT);
            //创建接受的Socket端
            DatagramSocket recesocket = new DatagramSocket(RECE_PORT);
            //发送线程建立
            send_thread = new Send_Thread(sendsocket, address);
            //接受线程的建立
            rece_thread = new Receive_Thread(recesocket);
            send_thread.start();
            rece_thread.start();
        }catch(Exception e)
        {
    
    
            System.out.println("Exception!");
        }

    }

}

Client (Jerry)

package Chat_UDP;
//杨丽冰 201831064402
import java.net.DatagramSocket;
import java.net.InetSocketAddress;

public class Chat_Client {
    
    
	//Jerry
	//声明端口号
	//201831064402 杨丽冰
    private static final int DEST_PORT = 9000;
    private static final int SEND_PORT = 10000;
    private static final int RECE_PORT = 8888;
    private static final String IP = "127.0.0.1";

    public static void main(String[] args)
    {
    
    
        try{
    
    
        	System.out.println("Jerry");
            Send_Thread send_thread = null;
            Receive_Thread rece_thread = null;
            InetSocketAddress address = null;
            //创建待接受数据包的目的机的端口号和IP地址
            address = new InetSocketAddress(IP, DEST_PORT);
            //创建发送的Socket端
            DatagramSocket sendsocket = new DatagramSocket(SEND_PORT);
            //创建接受的Socket端
            DatagramSocket recesocket = new DatagramSocket(RECE_PORT);
            //发送线程建立
            send_thread = new Send_Thread(sendsocket, address);
            //接受线程的建立
            rece_thread = new Receive_Thread(recesocket);
            send_thread.start();
            rece_thread.start();

        }catch(Exception e)
        {
    
    
            System.out.println("Exception!");
        }

    }
}

Guess you like

Origin blog.csdn.net/u011612364/article/details/111053554