zoukankan      html  css  js  c++  java
  • 2018-2019-20175225 实验五《网络编程与安全》实验报告

    实验步骤

    任务一

    • 两人一组结对编程
    • 结对实现中缀表达式转后缀表达式的功能 MyBC.java
    • 结对实现从上面功能中获取的表达式中实现后缀表达式求值的功能,调用MyDC.java

    实验过程

    • 将运算符写在两个操作数中间的表达式,称为“中缀表达式”,如1+2*(3-4)+5。在中缀表达式中,运算符具有不同的优先级,圆括号用于改变运算符的运算次序,所以求值过程不能直接按照从左到右的顺序进行。

    • 将运算符写在两个操作数之后的表达式称为“后缀表达式”,如上面的中缀表达式可转换为后缀表达式1 2 3 4 - * + 5 +。后缀表达式中没有括号,而且运算符没有优先级。后缀表达式的求值过程能够严格地从左到右按顺序进行,符合运算器的求值规律。

    • 表达式求值算法分两步进行:①中缀转后缀;②求后缀表达式的值。

    • 由中缀式求得后缀式可以使用栈,伪代码如下:

      • 设立一个栈,存放运算符,首先栈为空;
      • 从左到右扫描中缀式,若遇到操作数,直接输出,并输出一个空格作为两个操作数的分隔符;
      • 若遇到运算符,则与栈顶比较,比栈顶级别高则进栈,否则退出栈顶元素并输出,然后输出一个空格作分隔符;
      • 若遇到左括号,进栈;若遇到右括号,则一直退栈输出,直到退到左括号止。
      • 当栈变成空时,输出的结果即为后缀表达式。

    实验主要代码

    • 中缀转后缀
    package shiyan5;
    
    import java.util.Stack;
    public class MyBC{
        String jieguo = "";
        public MyBC (String[] args) {
            Stack<String> z = new Stack<String>();
            String t = "";
            for (int i = 0; i < args.length; i++) {
                switch (args[i]) {
                    case "(":
                        z.push(args[i]);
                        break;
                    case "+":
                    case "-":
                        while(z.empty() != true) {
                            t = z.pop();
                            if (t.equals("(")) {
                                z.push(t);
                                break;
                            }
                            jieguo = jieguo + t + " ";
                        }
                        z.push(args[i]);
                        break;
                    case "*":
                    case "/":
                        while(z.empty() != true) {
                            t = z.pop();
                            if (t.equals("+") || t.equals("-") || t.equals("(")) {
                                z.push(t);
                                break;
                            }
                            jieguo = jieguo + t + " ";
                        }
                        z.push(args[i]);
                        break;
                    case ")":
                        while (z.empty()== false) {
                            t = z.pop();
                            if (t.equals("(")) {
                                break;
                            } else {
                                jieguo = jieguo + t + " ";
                            }
                        }
                        break;
                    case" ":
                        break;
    
                    default:
                        jieguo = jieguo + args[i] + " ";
                        break;
                }
    
            }
    
            while (z.empty() == false) {
                jieguo = jieguo + z.pop() + " ";
            }
            System.out.println(jieguo);
        }
    }
    
    

    实验结果

    任务二

    • 结对编程:1人负责客户端,一人负责服务器
    • 注意责任归宿,要会通过测试证明自己没有问题
    • 基于Java Socket实现客户端/服务器功能,传输方式用TCP
    • 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式通过网络发送给服务器
    • 服务器接收到后缀表达式,调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
    • 客户端显示服务器发送过来的结果

    实验过程

    • 通过终端中输入ipconfig 或者使用InetAddress类的静态方法getLocalHost()获得一个InetAddress的对象获取服务器端IP地址
    • 客户端通过命令行输入待连接的服务器的IP地址
      • 调用InetAddress类中的geetByName方法获取输入的IP地址;
      • 创建一个套接字,可以使用Socket的构造方法,如:public Socket(java.lang.String host, int port) 其中,host是远程机器名或IP地址,port是远程应用程序的端口号。
      • 方法getInputStream() 获得一个输入流
      • 方法getOutputStream() 获得一个输出流
    • 服务器端调用ServerSocket实现套接字
      • 使用accept() 方法连接客户端和服务器的套接字
      • 方法getInputStream() 获得一个输入流
      • 方法getOutputStream() 获得一个输出流

    实验代码

    • 获取本机的地址
    package shiyan5;
    
    import java.net.*;
    public class getHostAddress {
        public static void main(String[] args) {
            try{
                InetAddress hostaddress = InetAddress.getLocalHost();
                System.out.println(hostaddress.toString());
            }catch (UnknownHostException e){
                System.out.println(e);
            }
        }
    }
    
    • 客户端
    package 实验五;
    
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.net.Socket;
    import java.util.Scanner;
    
    public class Client {
        public static void main(String[] args) {
            Scanner inn = new Scanner(System.in);
            Socket mysocket;
            DataInputStream in = null;
            DataOutputStream out = null;
            try{
                mysocket = new Socket("192.168.56.1",2010);
                in = new DataInputStream(mysocket.getInputStream());
                out = new DataOutputStream(mysocket.getOutputStream());
                System.out.println("请输入中缀表达式:");
                String infix = inn.nextLine();
                String [] str = infix.split(" ");
                System.out.println("已传递后缀表达式");
                MyBC suffix =new MyBC(str);
                out.writeUTF(suffix.jieguo);
                String result = in.readUTF();
                System.out.println("已收到计算结果"+result);
                Thread.sleep(500);
            }catch (Exception e){
                System.out.println("双方已断开连接"+e);
            }
        }
    }
    
    • 服务器端
    package 实验五;
    
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.net.ServerSocket;
    import java.net.Socket;
    public class Sever {
        public static void main(String[] args) {
            ServerSocket serverForClient = null;
            Socket socketOnServer = null;
            DataOutputStream out = null;
            DataInputStream in = null;
    
            try{
                serverForClient = new ServerSocket(2010);
            }catch (IOException e){
                System.out.println("双方已断开连接"+e);
            }
            try{
                System.out.println("准备接受对方传来的问题");
                socketOnServer = serverForClient.accept();
                out = new DataOutputStream(socketOnServer.getOutputStream());
                in = new DataInputStream(socketOnServer.getInputStream());
                String suffix = in.readUTF();
                String [] str = suffix.split(" ");
                System.out.println("收到问题,正在解决:"+suffix);
                System.out.println("已传输得出结果:");
                MyDC myDC = new MyDC(str);
                String answer =  String.valueOf(myDC.answer);
                out.writeUTF(answer+"");
                Thread.sleep(500);
            }catch (Exception e){
                System.out.println("双方已断开连接");
            }
        }
    }
    

    实验结果

    • 客户端

    • 服务器端

    任务三

    • 加密结对编程:1人负责客户端,一人负责服务器
    • 注意责任归宿,要会通过测试证明自己没有问题
    • 基于Java Socket实现客户端/服务器功能,传输方式用TCP
    • 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用DES或AES算法加密后通过网络把密文发送给服务器
    • 服务器接收到后缀表达式表达式后,进行解密(和客户端协商密钥,可以用数组保存),然后调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
    • 客户端显示服务器发送过来的结果

    实验过程

    • 实现DES加密主要有以下几个步骤:
      • 对称密钥的生成和保存;
      • 使用对称密钥进行加密和解密;
      • 从文件中获取加密时使用的密钥,使用密钥进行解密;
    • 生成密钥文件

    实验代码

    • 客户端
    package 实验五;
    
    import javax.crypto.Cipher;
    import javax.crypto.KeyGenerator;
    import javax.crypto.SecretKey;
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.net.Socket;
    import java.util.Scanner;
    
    public class Client1{
        public static void main(String[] args) {
            Scanner inn = new Scanner(System.in);
            Socket mysocket;
            DataInputStream in = null;
            DataOutputStream out = null;
            try{
                mysocket = new Socket("192.168.56.1",2010);
                in = new DataInputStream(mysocket.getInputStream());
                out = new DataOutputStream(mysocket.getOutputStream());
                KeyGenerator kg = KeyGenerator.getInstance("DESede");
                kg.init(168);
                SecretKey k = kg.generateKey();
                byte []kb = k.getEncoded();
                out.writeUTF(kb.length+ "");
                System.out.println("产生的密钥为");
                for(int i=0;i<kb.length;i++) {
                    System.out.print(kb[i]+ " ");
                    out.writeUTF(kb[i] +"");
                }
                System.out.println("
    请输入中缀表达式:");
                String infix = inn.nextLine();
                String [] str = infix.split(" ");
                System.out.println("后缀表达式为");
                MyBC suffix =new MyBC(str);
                Cipher cp = Cipher.getInstance("DESede");
                cp.init(Cipher.ENCRYPT_MODE,k);
                byte ptext[] = suffix.jieguo.getBytes("UTF8");
                byte ctext[] = cp.doFinal(ptext);
                out.writeUTF(ctext.length + "");
                for(int i=0;i<ctext.length;i++) {
                    out.writeUTF(ctext[i] +"");
                }
                String result = in.readUTF();
                System.out.println("已收到计算结果"+result);
                Thread.sleep(500);
            }catch (Exception e){
                System.out.println("双方已断开连接"+e);
            }
        }
    }
    
    • 服务器端
    package 实验五;
    
    import javax.crypto.Cipher;
    import javax.crypto.spec.SecretKeySpec;
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.net.ServerSocket;
    import java.net.Socket;
    public class Sever1{
        public static void main(String[] args) {
            ServerSocket serverForClient = null;
            Socket socketOnServer = null;
            DataOutputStream out = null;
            DataInputStream in = null;
            try{
                serverForClient = new ServerSocket(2010);
            }catch (IOException e){
                System.out.println("双方已断开连接"+e);
            }
            try{
                System.out.println("准备接受对方传来的问题");
                socketOnServer = serverForClient.accept();
                out = new DataOutputStream(socketOnServer.getOutputStream());
                in = new DataInputStream(socketOnServer.getInputStream());
                String keylength = in.readUTF();
                byte []kb = new byte[Integer.parseInt(keylength)];
                System.out.println("收到的密钥为:");
                for(int i = 0;i<Integer.parseInt(keylength);i++) {
                    String str = in.readUTF();
                    kb[i] = Byte.parseByte(str);
                    System.out.print(kb[i] + " ");
                }
                SecretKeySpec k = new SecretKeySpec(kb, "DESede");
                Cipher cp = Cipher.getInstance("DESede");
                cp.init(Cipher.DECRYPT_MODE, k);
                String clength = in.readUTF();
                byte ctext[] = new byte[Integer.parseInt(clength)];
                for (int i = 0;i<Integer.parseInt(clength);i++) {
                    String temp = in.readUTF();
                    ctext[i] = Byte.parseByte(temp);
                }
                byte[] ptext = cp.doFinal(ctext);
                String suffix = new String(ptext,"UTF8");
                String [] str = suffix.split(" ");
                System.out.println("
    收到问题,解密后的后缀表达式为:"+suffix);
                System.out.println("已传输得出结果:");
                MyDC myDC = new MyDC(str);
                String answer =  String.valueOf(myDC.answer);
                out.writeUTF(answer+"");
                Thread.sleep(500);
            }catch (Exception e){
                System.out.println("双方已断开连接");
            }
        }
    }
    

    实验结果

    • 客户端

    • 服务器端

    任务四

    • 密钥分发结对编程:1人负责客户端,一人负责服务器
    • 注意责任归宿,要会通过测试证明自己没有问题
    • 基于Java Socket实现客户端/服务器功能,传输方式用TCP
    • 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用DES或AES算法加密通过网络把密文发送给服务器
    • 客户端和服务器用DH算法进行DES或AES算法的密钥交换
    • 服务器接收到后缀表达式表达式后,进行解密,然后调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
    • 客户端显示服务器发送过来的结果

    实验过程

    • 两人先使用Key_DH类生成各自的DH公钥和私钥
    • 俩人使用对方的公钥和自己的私钥,用KeyAgree,生成共享密钥
    • 客户端使用共享密钥对原有的密钥进行加密,并把密文和加密后的密钥传输给服务器
    • 服务器先用共享密钥对客户端加密的密钥进行解密,再用解密后的密钥解密密文

    实验代码

    • 客户端
    package 实验五;
    
    import javax.crypto.Cipher;
    import javax.crypto.spec.SecretKeySpec;
    import java.io.*;
    import java.security.*;
    import java.util.Scanner;
    import java.net.*;
    public class Client2 {
        public static void main(String[] args) {
            Scanner inn = new Scanner(System.in
    
            );
            Socket mysocket;
            DataInputStream in = null;
            DataOutputStream out = null;
            try{
                mysocket = new Socket("192.168.56.1",2010);
                        in = new DataInputStream(mysocket.getInputStream());
                out = new DataOutputStream(mysocket.getOutputStream());
                Key_DH.DH ("Lpub.dat","Lpri.dat");
                FileInputStream my = new FileInputStream("Lpub.dat");
                ObjectInputStream mypub = new ObjectInputStream(my);
                Key kp = (Key) mypub.readObject();
                ByteArrayOutputStream DH = new ByteArrayOutputStream();
                ObjectOutputStream myDH = new ObjectOutputStream(DH);
                myDH.writeObject(kp);
                byte []pub = DH.toByteArray();
                out.writeUTF(pub.length+"");
                for(int i=0;i<pub.length;i++) {
                    out.writeUTF(pub[i]+ "");
                }
                Thread.sleep(1000);
                int length = Integer.parseInt(in.readUTF());
                byte cpub[] = new byte[length];
                for(int i=0;i<length;i++) {
                    String temp = in.readUTF();
                    cpub[i] = Byte.parseByte(temp);
                }
                ByteArrayInputStream ckey1 = new ByteArrayInputStream(cpub);
                ObjectInputStream ckey = new ObjectInputStream(ckey1);
                Key k = (Key) ckey.readObject();
                FileOutputStream f2 = new FileOutputStream("W1pub.dat");
                ObjectOutputStream b2 = new ObjectOutputStream(f2);
                b2.writeObject(k);
                KeyAgree.Agree("W1pub.dat","Lpri.dat");
                FileInputStream f = new FileInputStream("sb.dat");
                byte[] keysb = new byte[24];
                f.read(keysb);
                System.out.println("公共密钥为:");
                for (int i = 0;i<24;i++) {
                    System.out.print(keysb[i]+" ");
                }
                System.out.println("
    请输入中缀表达式:");
                String infix = inn.nextLine();
                String [] str = infix.split(" ");
                System.out.println("已传递后缀表达式");
                MyBC suffix =new MyBC(str);
                SecretKeySpec k1 = new SecretKeySpec(keysb, "DESede");
                Cipher cp = Cipher.getInstance("DESede");
                cp.init(Cipher.ENCRYPT_MODE, k1);
                byte ptext[] = suffix.jieguo.getBytes("UTF8");
                byte ctext[] = cp.doFinal(ptext);
                System.out.println("加密后的后缀表达式为:");
                for (int i = 0; i < ctext.length; i++) {
                    System.out.print(ctext[i] + " ");
                }
                out.writeUTF(ctext.length + "");
                for (int i = 0; i < ctext.length; i++) {
                    out.writeUTF(ctext[i] + "");
                }
                String result = in.readUTF();
                System.out.println("
    已收到计算结果"+result);
                Thread.sleep(500);
            }catch (Exception e){
                System.out.println("双方已断开连接"+e);
            }
        }
    }
    
    • 服务器端
    package 实验五;
    
    import javax.crypto.Cipher;
    import javax.crypto.spec.SecretKeySpec;
    import java.io.*;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.security.Key;
    public class Sever2{
        public static void main(String[] args) {
            ServerSocket serverForClient = null;
            Socket socketOnServer = null;
            DataOutputStream out = null;
            DataInputStream in = null;
            try{
                serverForClient = new ServerSocket(2010);
            }catch (IOException e){
                System.out.println("双方已断开连接"+e);
            }
            try{
                System.out.println("准备接受对方传来的问题");
                socketOnServer = serverForClient.accept();
                out = new DataOutputStream(socketOnServer.getOutputStream());
                in = new DataInputStream(socketOnServer.getInputStream());
                Key_DH.DH("Wpub.dat","Wpri.dat");
                int length = Integer.parseInt(in.readUTF());
                byte cpub[] = new byte[length];
                for(int i=0;i<length;i++) {
                    String temp = in.readUTF();
                    cpub[i] = Byte.parseByte(temp);
                }
                ByteArrayInputStream ckey1 = new ByteArrayInputStream(cpub);
                ObjectInputStream ckey = new ObjectInputStream(ckey1);
                Key k1 = (Key) ckey.readObject();
                FileOutputStream f2 = new FileOutputStream("Lpub.dat");
                ObjectOutputStream b2 = new ObjectOutputStream(f2);
                b2.writeObject(k1);
                FileInputStream my = new FileInputStream("Wpub.dat");
                ObjectInputStream mypub = new ObjectInputStream(my);
                Key kp = (Key) mypub.readObject();
                ByteArrayOutputStream DH = new ByteArrayOutputStream();
                ObjectOutputStream myDH = new ObjectOutputStream(DH);
                myDH.writeObject(kp);
                byte []pub = DH.toByteArray();
                out.writeUTF(pub.length+"");
                for(int i=0;i<pub.length;i++) {
                    out.writeUTF(pub[i]+ "");
                }
                KeyAgree.Agree("Lpub.dat","Wpri.dat");
                FileInputStream f = new FileInputStream("sb.dat");
                byte[] keysb = new byte[24];
                f.read(keysb);
                System.out.println("公共密钥为:");
                for (int i = 0;i<24;i++) {
                    System.out.print(keysb[i]+" ");
                }
                SecretKeySpec k = new SecretKeySpec(keysb, "DESede");
                Cipher cp = Cipher.getInstance("DESede");
                cp.init(Cipher.DECRYPT_MODE, k);
                String clength = in.readUTF();
                byte ctext[] = new byte[Integer.parseInt(clength)];
                for (int i = 0; i < Integer.parseInt(clength); i++) {
                    String temp = in.readUTF();
                    ctext[i] = Byte.parseByte(temp);
                }
                byte[] ptext = cp.doFinal(ctext);
                String suffix = new String(ptext, "UTF8");
                String [] str = suffix.split(" ");
                System.out.println("
    收到问题,正在解密后缀表达式:"+suffix);
                System.out.println("已传输得出结果:");
                MyDC myDC = new MyDC(str);
                String answer =  String.valueOf(myDC.answer);
                out.writeUTF(answer+"");
                Thread.sleep(500);
            }catch (Exception e){
                System.out.println("双方已断开连接");
            }
        }
    }
    
    • KeyAgree
    package 实验五;
    
    import javax.crypto.KeyAgreement;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.ObjectInputStream;
    import java.security.PrivateKey;
    import java.security.PublicKey;
    
    public class KeyAgree {
        public static void Agree(String str1,String str2) throws Exception{
            // 读取对方的DH公钥
            FileInputStream f1=new FileInputStream(str1);
            ObjectInputStream b1=new ObjectInputStream(f1);
            PublicKey  pbk=(PublicKey)b1.readObject( );
    //读取自己的DH私钥
            FileInputStream f2=new FileInputStream(str2);
            ObjectInputStream b2=new ObjectInputStream(f2);
            PrivateKey  prk=(PrivateKey)b2.readObject( );
            // 执行密钥协定
            KeyAgreement ka=KeyAgreement.getInstance("DH");
            ka.init(prk);
            ka.doPhase(pbk,true);
            //生成共享信息
            byte[ ] sb=ka.generateSecret();
            FileOutputStream fsb = new FileOutputStream("sb.dat");
            fsb.write(sb);
        }
    }
    
    • Key_DH
    package 实验五;
    
    import javax.crypto.spec.DHParameterSpec;
    import java.io.FileOutputStream;
    import java.io.ObjectOutputStream;
    import java.math.BigInteger;
    import java.security.KeyPair;
    import java.security.KeyPairGenerator;
    import java.security.PrivateKey;
    import java.security.PublicKey;
    
    public class Key_DH{
        private static final byte skip1024ModulusBytes[] = {
                (byte)0xF4, (byte)0x88, (byte)0xFD, (byte)0x58,
                (byte)0x4E, (byte)0x49, (byte)0xDB, (byte)0xCD,
                (byte)0x20, (byte)0xB4, (byte)0x9D, (byte)0xE4,
                (byte)0x91, (byte)0x07, (byte)0x36, (byte)0x6B,
                (byte)0x33, (byte)0x6C, (byte)0x38, (byte)0x0D,
                (byte)0x45, (byte)0x1D, (byte)0x0F, (byte)0x7C,
                (byte)0x88, (byte)0xB3, (byte)0x1C, (byte)0x7C,
                (byte)0x5B, (byte)0x2D, (byte)0x8E, (byte)0xF6,
                (byte)0xF3, (byte)0xC9, (byte)0x23, (byte)0xC0,
                (byte)0x43, (byte)0xF0, (byte)0xA5, (byte)0x5B,
                (byte)0x18, (byte)0x8D, (byte)0x8E, (byte)0xBB,
                (byte)0x55, (byte)0x8C, (byte)0xB8, (byte)0x5D,
                (byte)0x38, (byte)0xD3, (byte)0x34, (byte)0xFD,
                (byte)0x7C, (byte)0x17, (byte)0x57, (byte)0x43,
                (byte)0xA3, (byte)0x1D, (byte)0x18, (byte)0x6C,
                (byte)0xDE, (byte)0x33, (byte)0x21, (byte)0x2C,
                (byte)0xB5, (byte)0x2A, (byte)0xFF, (byte)0x3C,
                (byte)0xE1, (byte)0xB1, (byte)0x29, (byte)0x40,
                (byte)0x18, (byte)0x11, (byte)0x8D, (byte)0x7C,
                (byte)0x84, (byte)0xA7, (byte)0x0A, (byte)0x72,
                (byte)0xD6, (byte)0x86, (byte)0xC4, (byte)0x03,
                (byte)0x19, (byte)0xC8, (byte)0x07, (byte)0x29,
                (byte)0x7A, (byte)0xCA, (byte)0x95, (byte)0x0C,
                (byte)0xD9, (byte)0x96, (byte)0x9F, (byte)0xAB,
                (byte)0xD0, (byte)0x0A, (byte)0x50, (byte)0x9B,
                (byte)0x02, (byte)0x46, (byte)0xD3, (byte)0x08,
                (byte)0x3D, (byte)0x66, (byte)0xA4, (byte)0x5D,
                (byte)0x41, (byte)0x9F, (byte)0x9C, (byte)0x7C,
                (byte)0xBD, (byte)0x89, (byte)0x4B, (byte)0x22,
                (byte)0x19, (byte)0x26, (byte)0xBA, (byte)0xAB,
                (byte)0xA2, (byte)0x5E, (byte)0xC3, (byte)0x55,
                (byte)0xE9, (byte)0x2F, (byte)0x78, (byte)0xC7
        };
        // The SKIP 1024 bit modulus
        private static final BigInteger skip1024Modulus
                = new BigInteger(1, skip1024ModulusBytes);
        // The base used with the SKIP 1024 bit modulus
        private static final BigInteger skip1024Base = BigInteger.valueOf(2);
        public static void DH(String str1,String str2) throws Exception{
            DHParameterSpec DHP=
                    new DHParameterSpec(skip1024Modulus,skip1024Base);
    
            KeyPairGenerator kpg= KeyPairGenerator.getInstance("DH");
            kpg.initialize(DHP);
            KeyPair kp=kpg.genKeyPair();
    
            PublicKey pbk=kp.getPublic();
            PrivateKey prk=kp.getPrivate();
            // 保存公钥
            FileOutputStream  f1=new FileOutputStream(str1);
            ObjectOutputStream b1=new  ObjectOutputStream(f1);
            b1.writeObject(pbk);
            // 保存私钥
            FileOutputStream  f2=new FileOutputStream(str2);
            ObjectOutputStream b2=new  ObjectOutputStream(f2);
            b2.writeObject(prk);
        }
    }
    

    实验结果

    • 客户端

    • 服务器端

    任务五

    • 完整性校验结对编程:1人负责客户端,一人负责服务器
    • 注意责任归宿,要会通过测试证明自己没有问题
    • 基于Java Socket实现客户端/服务器功能,传输方式用TCP
    • 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加密通过网络把密文和明文的MD5値发送给服务器
    • 客户端和服务器用DH算法进行3DES或AES算法的密钥交换
    • 服务器接收到后缀表达式表达式后,进行解密,解密后计算明文的MD5值,和客户端传来的MD5进行比较,一致则调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
    • 客户端显示服务器发送过来的结果

    实验代码

    • 客户端
    package 实验五;
    
    import javax.crypto.Cipher;
    import javax.crypto.spec.SecretKeySpec;
    import java.io.*;
    import java.net.Socket;
    import java.security.Key;
    import java.util.Scanner;
    
    public class Client3 {
        public static void main(String[] args) {
            Scanner inn = new Scanner(System.in
    
            );
            Socket mysocket;
            DataInputStream in = null;
            DataOutputStream out = null;
            try{
                mysocket = new Socket("192.168.56.1",2010);
                        in = new DataInputStream(mysocket.getInputStream());
                out = new DataOutputStream(mysocket.getOutputStream());
                Key_DH.DH("Lpub.dat","Lpri.dat");
                FileInputStream my = new FileInputStream("Lpub.dat");
                ObjectInputStream mypub = new ObjectInputStream(my);
                Key kp = (Key) mypub.readObject();
                ByteArrayOutputStream DH = new ByteArrayOutputStream();
                ObjectOutputStream myDH = new ObjectOutputStream(DH);
                myDH.writeObject(kp);
                byte []pub = DH.toByteArray();
                out.writeUTF(pub.length+"");
                for(int i=0;i<pub.length;i++) {
                    out.writeUTF(pub[i]+ "");
                }
                Thread.sleep(1000);
                int length = Integer.parseInt(in.readUTF());
                byte cpub[] = new byte[length];
                for(int i=0;i<length;i++) {
                    String temp = in.readUTF();
                    cpub[i] = Byte.parseByte(temp);
                }
                ByteArrayInputStream ckey1 = new ByteArrayInputStream(cpub);
                ObjectInputStream ckey = new ObjectInputStream(ckey1);
                Key k = (Key) ckey.readObject();
                FileOutputStream f2 = new FileOutputStream("W1pub.dat");
                ObjectOutputStream b2 = new ObjectOutputStream(f2);
                b2.writeObject(k);
                KeyAgree.Agree("W1pub.dat","Lpri.dat");
                FileInputStream f = new FileInputStream("sb.dat");
                byte[] keysb = new byte[24];
                f.read(keysb);
                System.out.println("公共密钥为:");
                for (int i = 0;i<24;i++) {
                    System.out.print(keysb[i]+" ");
                }
                System.out.println("
    请输入中缀表达式:");
                String infix = inn.nextLine();
                String [] str = infix.split(" ");
                System.out.println("已传递后缀表达式");
                MyBC suffix =new MyBC(str);
                String mtoMD5 = DigestPass.MD5(suffix.jieguo);
                System.out.println("明文的MD5值为:"+mtoMD5);
                out.writeUTF(mtoMD5);
                SecretKeySpec k1 = new SecretKeySpec(keysb, "DESede");
                Cipher cp = Cipher.getInstance("DESede");
                cp.init(Cipher.ENCRYPT_MODE, k1);
                byte ptext[] = suffix.jieguo.getBytes("UTF8");
                byte ctext[] = cp.doFinal(ptext);
                System.out.println("加密后的后缀表达式为:");
                for (int i = 0; i < ctext.length; i++) {
                    System.out.print(ctext[i] + " ");
                }
                out.writeUTF(ctext.length + "");
                for (int i = 0; i < ctext.length; i++) {
                    out.writeUTF(ctext[i] + "");
                }
                String result = in.readUTF();
                System.out.println("
    已收到计算结果"+result);
                Thread.sleep(500);
            }catch (Exception e){
                System.out.println("双方已断开连接"+e);
            }
        }
    }
    
    • 服务器端
    package 实验五;
    
    import javax.crypto.Cipher;
    import javax.crypto.spec.SecretKeySpec;
    import java.io.*;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.security.Key;
    public class Sever3 {
        public static void main(String[] args) {
            ServerSocket serverForClient = null;
            Socket socketOnServer = null;
            DataOutputStream out = null;
            DataInputStream in = null;
    
            try{
                serverForClient = new ServerSocket(2010);
            }catch (IOException e){
                System.out.println("双方已断开连接"+e);
            }
            try{
                System.out.println("准备接受对方传来的问题");
                socketOnServer = serverForClient.accept();
                out = new DataOutputStream(socketOnServer.getOutputStream());
                in = new DataInputStream(socketOnServer.getInputStream());
                Key_DH.DH("Wpub.dat","Wpri.dat");
                int length = Integer.parseInt(in.readUTF());
                byte cpub[] = new byte[length];
                for(int i=0;i<length;i++) {
                    String temp = in.readUTF();
                    cpub[i] = Byte.parseByte(temp);
                }
                ByteArrayInputStream ckey1 = new ByteArrayInputStream(cpub);
                ObjectInputStream ckey = new ObjectInputStream(ckey1);
                Key k1 = (Key) ckey.readObject();
                FileOutputStream f2 = new FileOutputStream("L1pub.dat");
                ObjectOutputStream b2 = new ObjectOutputStream(f2);
                b2.writeObject(k1);
                FileInputStream my = new FileInputStream("Wpub.dat");
                ObjectInputStream mypub = new ObjectInputStream(my);
                Key kp = (Key) mypub.readObject();
                ByteArrayOutputStream DH = new ByteArrayOutputStream();
                ObjectOutputStream myDH = new ObjectOutputStream(DH);
                myDH.writeObject(kp);
                byte []pub = DH.toByteArray();
                out.writeUTF(pub.length+"");
                for(int i=0;i<pub.length;i++) {
                    out.writeUTF(pub[i]+ "");
                }
                KeyAgree.Agree("L1pub.dat","Wpri.dat");
                FileInputStream f = new FileInputStream("sb.dat");
                byte[] keysb = new byte[24];
                f.read(keysb);
                System.out.println("公共密钥为:");
                for (int i = 0;i<24;i++) {
                    System.out.print(keysb[i]+" ");
                }
                String c = in.readUTF();
                SecretKeySpec k = new SecretKeySpec(keysb, "DESede");
                Cipher cp = Cipher.getInstance("DESede");
                cp.init(Cipher.DECRYPT_MODE, k);
                String clength = in.readUTF();
                byte ctext[] = new byte[Integer.parseInt(clength)];
                for (int i = 0; i < Integer.parseInt(clength); i++) {
                    String temp = in.readUTF();
                    ctext[i] = Byte.parseByte(temp);
                }
                byte[] ptext = cp.doFinal(ctext);
                String suffix = new String(ptext, "UTF8");
                String [] str = suffix.split(" ");
                System.out.println("
    收到问题,解密后缀表达式为:"+suffix);
                String mtoMD5 = DigestPass.MD5(suffix);
                System.out.println("MD5的值为"+ mtoMD5);
                if(mtoMD5.equals(c)) {
                    System.out.println("传递的MD5值和解密的后缀表达式的MD5值相同,可以解密!");
                    System.out.println("已传输得出结果:");
                    MyDC myDC = new MyDC(str);
                    String answer = String.valueOf(myDC.answer);
                    out.writeUTF(answer + "");
                }
                else {
                    System.out.println("密文有误,不能解密!");
                }
                Thread.sleep(500);
            }catch (Exception e){
                System.out.println("双方已断开连接");
            }
        }
    }
    

    实验结果

    • 客户端

    • 服务器端

    码云链接

  • 相关阅读:
    打开安装 好的Microsoft Dynamics CRM 4.0 报错误为 Caller does not have enough privilege to set CallerOriginToken to the specified value 的解决办法
    基于 Windows Server 2008 的计算机对 Microsoft Dynamics CRM 4.0 的支持
    Microsoft Dynamics CRM 4.0 如何添加自定义按钮
    Microsoft Dynamics CRM 4.0 Plugin 取值,赋值,查询
    C# 中的 enum(枚举) 类型使用例子
    vue事件的绑定
    表单验证2
    node中模块
    node模块的引入
    node中的读文件
  • 原文地址:https://www.cnblogs.com/zhangdeshuai/p/10933299.html
Copyright © 2011-2022 走看看