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

    2018-2019-2 20175226 实验五《网络编程与安全》实验报告

    任务一

    实验要求

    -两人一组结对编程:
    - 参考http://www.cnblogs.com/rocedu/p/6766748.html#SECDSA
    - 结对实现中缀表达式转后缀表达式的功能 MyBC.java
    - 结对实现从上面功能中获取的表达式中实现后缀表达式求值的功能,调用MyDC.java
    - 上传测试代码运行结果截图和码云链接

    实验原理

    • 中缀转后缀表达式
      • 遇到数字,我们就直接将其输出。
      • 遇到非数字时,若栈为空或者该符号为左括号或者栈顶元素为括号,直接入栈。
      • 遇到一个右括号,持续出栈并输出符号,直到栈顶元素为左括号,然后将左括号出栈(注意,左括号只出栈,不输出),右括号不入栈。
      • 遇到运算符号且栈非空,查看栈顶元素,如果栈顶元素的运算优先级大于或者等于该运算符号,则持续出栈,直到栈顶元素优先级小于该运算符。最后将该元素入栈。
      • 我们读到了输入的末尾,则将栈中所有元素依次弹出。
    • 通过后缀表达式计算结果
      • 建立一个空栈,遇到数字就入栈,遇到符号就以符号前面的两个数为运算数进行计算

    实验代码

    • 中缀转后缀表达式MyBC.java
    package 实验五;
    
    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);
        }
    }
    
    • 后缀表达式计算MyDC.java
    package 实验五;
    
    import java.util.Stack;
    public class MyDC{
        private static Integer answer;
        public MyDC (String[] args) {
            Stack<String> z = new Stack<String>();
            int num1,num2,d;
            for(int i=0;i<args.length;i++) {
                switch (args[i]){
                    case"+":
                        num2 = Integer.valueOf(z.pop());
                        num1 = Integer.valueOf(z.pop());
                        d = num1+num2;
                        z.push(String.valueOf(d));
                        break;
                    case"-":
                        num2 = Integer.valueOf(z.pop());
                        num1 = Integer.valueOf(z.pop());
                        d = num1-num2;
                        z.push(String.valueOf(d));
                        break;
                    case"*":
                        num2 = Integer.valueOf(z.pop());
                        num1 = Integer.valueOf(z.pop());
                        d = num1*num2;
                        z.push(String.valueOf(d));
                        break;
                    case"/":
                        num2 = Integer.valueOf(z.pop());
                        num1 = Integer.valueOf(z.pop());
                        d = num1/num2;
                        z.push(String.valueOf(d));
                        break;
                    case"":
                    case" ":
                        break;
    
                    default:
                        z.push(args[i]);
                        break;
                }
            }
            while (z.empty() == false) {
                answer =  Integer.valueOf(z.pop());
            }
            System.out.println(answer);
        }
    }
    
    • 测试代码 shiyan5_1 .java
    package 实验五;
    
    import java.util.Scanner;
    
    public class shiyan5_1 {
        public static void main(String[] args) {
            String question = "";
            int result;
            Scanner scanner = new Scanner(System.in);
            System.out.println("请输入题目:");
            question = scanner.nextLine();
            String [] str = question.split(" ");
            System.out.println("转置结果如下:");
            MyBC translate = new MyBC(str);
            String [] str2 = translate.jieguo.split(" ");
            System.out.println("计算结果如下:");
            MyDC answer = new MyDC(str2);
        }
    }
    

    实验截图

    任务二

    实验要求

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

    实验过程及原理

    • 使用InetAddress类的静态方法getLocalHost()获得一个InetAddress的对象,该对象含有本地机器的IP地址
    • 客户端套接字:Socket clientSocket = new Socket("服务器的IP地址",一个端口号)
    • SeverSocket对象与服务器端套接字:SeverSocket severForClient = new SeverSocket(端口号)
    • 使用accept()方法将客户端和服务器的套接字连接起来:Socket sc = severForClient.accept()

    实验代码

    • 访问本机IPgetHostAddress.java
    package 实验五;
    
    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);
            }
        }
    }
    
    • 客户端Client.java
    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("169.254.92.198",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);
            }
        }
    }
    
    • 服务器Sever.java
    package 实验五;
    
    import com.sun.xml.internal.ws.policy.privateutil.PolicyUtils;
    import java.io.*;
    import java.net.*;
    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("双方已断开连接");
            }
        }
    }
    

    实验截图

    • 访问本机IP

    • 客户端

    • 服务器

    任务三

    实验要求

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

    实验原理及过程

    • 客户端
      • 获取并初始化密钥生成器KeyGenerator kg=KeyGenerator.getInstance("DESede")kg.init(168);
      • 生成密钥SecretKey k=kg.generateKey( );
      • 传送密钥长度及密钥内容
      • 创建并初始化密码器Cipher cp=Cipher.getInstance("DESede")cp.init(Cipher.ENCRYPT_MODE, k);
      • 执行加密byte []ptext=cp.doFinal(ctext)
    • 服务器
      • 接收密钥长度、密钥内容
      • 创建并初始化密码器Cipher cp=Cipher.getInstance("DESede")cp.init(Cipher.DECRYPT_MODE, k);
      • 执行解密byte []ptext=cp.doFinal(ctext)

    实验代码

    • 客户端Client.java
    package 实验五;
    
    import java.io.*;
    import java.net.*;
    import javax.crypto.*;
    import java.util.Scanner;
    
    public class Client5_3 {
        public static void main(String[] args) {
            Scanner inn = new Scanner(System.in);
            Socket mysocket;
            DataInputStream in = null;
            DataOutputStream out = null;
            try{
                mysocket = new Socket("169.254.92.198",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);
            }
        }
    }
    
    • 服务器Sever,java
    package 实验五;
    
    import com.sun.xml.internal.ws.policy.privateutil.PolicyUtils;
    import java.io.*;
    import java.net.*;
    import javax.crypto.*;
    import javax.crypto.spec.*;
    public class Sever5_3 {
        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("双方已断开连接");
            }
        }
    }
    

    实验截图

    • 客户端

    • 服务器

    任务四

    实验要求

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

    实验原理及过程

    • 客户端和服务器分别产生自己的公钥和私钥,并用过字节数组的形式分别向另一方传递自己的公钥;
    • 客户端和服务器接受对方的公钥后利用自己的私钥创建共享密钥;
    • 创建并初始化密钥协定对象KeyAgreement ka=KeyAgreement.getInstance("DH")ka.init(prk);
    • 执行密钥协定ka.doPhase(pbk,true);
    • 生成共享信息byte[ ] sb=ka.generateSecret();
    • 从文件中读取信息并给出共享密钥

    实验代码

    • key_DH.javakeyAgree.java
    package 实验五;
    
    import java.io.*;
    import java.math.*;
    import java.security.*;
    import javax.crypto.spec.*;
    
    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);
        }
    } 
    
    package 实验五;
    
    import java.io.*;
    import java.math.*;
    import java.security.*;
    import java.security.spec.*;
    import javax.crypto.*;
    import javax.crypto.spec.*;
    import javax.crypto.interfaces.*;
    
    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);
        }
    }
    
    • 客户端Client5_4.java
    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 Client5_4 {
        public static void main(String[] args) {
            Scanner inn = new Scanner(System.in);
            Socket mysocket;
            DataInputStream in = null;
            DataOutputStream out = null;
            try{
                mysocket = new Socket("169.254.92.198",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);
            }
        }
    }
    
    • 服务器Sever5_4,java
    package 实验五;
    
    import com.sun.xml.internal.ws.policy.privateutil.PolicyUtils;
    import javax.crypto.Cipher;
    import javax.crypto.spec.SecretKeySpec;
    import java.io.*;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.security.*;
    public class Sever5_4 {
        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("双方已断开连接");
            }
        }
    }
    

    实验截图

    • 客户端

    • 服务器

    任务五

    实验要求

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

    实验原理

    • Java密码学算法中“Java摘要算法- MD5”部分的内容

    实验代码

    • MD5DigestPass.java
    package 实验五;
    
    import java.security.*;
    
    public class DigestPass{
        public static String MD5(String str) throws Exception{
            String x=str;
            MessageDigest m=MessageDigest.getInstance("MD5");
            m.update(x.getBytes("UTF8"));
            byte s[ ]=m.digest( );
            String result="";
            for (int i=0; i<s.length; i++){
                result+=Integer.toHexString((0x000000ff & s[i]) |
                        0xffffff00).substring(6);
            }
            return result;
        }
    }
    
    • 客户端Client5_5
    package 实验五;
    
    import javax.crypto.Cipher;
    import javax.crypto.spec.SecretKeySpec;
    import java.io.*;
    import java.net.Socket;
    import java.security.*;
    import java.util.Scanner;
    import java.net.*;
    
    public class Client5_5 {
        public static void main(String[] args) {
            Scanner inn = new Scanner(System.in);
            Socket mysocket;
            DataInputStream in = null;
            DataOutputStream out = null;
            try{
                mysocket = new Socket("169.254.92.198",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);
            }
        }
    }
    
    • 服务器Sever.java
    package 实验五;
    
    import com.sun.xml.internal.ws.policy.privateutil.PolicyUtils;
    import javax.crypto.Cipher;
    import javax.crypto.spec.SecretKeySpec;
    import java.io.*;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.security.*;
    public class Sever5_5 {
        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("双方已断开连接");
            }
        }
    }
    

    实验截图

    • 客户端

    • 服务器

    跳转链接

    码云链接

    搭档博客链接

  • 相关阅读:
    使用C#实现DHT磁力搜索的BT种子后端管理程序+数据库设计(开源)
    便携版WinSCP在命令行下同步文件夹
    ffmpeg (ffprobe)分析文件关键帧时间点
    sqlite删除数据或者表后,回收数据库文件大小
    ubuntu 20.04下 freeswitch 配合 fail2ban 防恶意访问
    ffmpeg使用nvenc编码的结论记录
    PC版跑跑卡丁车 故事模式 亚瑟传说章节 卡美洛庆典 2阶段 心灵之眼 攻略
    There was an error loading or playing the video
    Nvidia RTX Voice 启动报错修复方法
    火狐浏览器 关闭跨域限制
  • 原文地址:https://www.cnblogs.com/20175226wpy/p/10933895.html
Copyright © 2011-2022 走看看