• 实验五实验报告


    一、实验报告封面

    课程:Java程序设计 班级:1752班 姓名:罗乐琦 学号:20175219
    指导教师:娄嘉鹏 实验日期:2019年5月28日
    实验时间:--- 实验序号:实验五
    实验名称:网络编程与安全

    二、实验内容与步骤

    任务一要求

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

    实验代码

    getHostAddress.java

    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);
            }
        }
    }
    

    MyBC.java

    import java.io.*;
    import java.util.Stack;
    
    public class MyBC {
        public static void main(String[] args) {
            int i, f;
            double result;
            int zuokuohao1 = 0;
            String ch2 = new String();
            BufferedReader buf = new BufferedReader(new InputStreamReader(System.in));
            try {
                String str = buf.readLine();
                f = chu0.chu0(str);
                if (f == 0) {
                    char[] ch1 = str.toCharArray();
                    int len1 = ch1.length;
                    Stack<Character> operators = new Stack<>();
                    Stack output = new Stack<>();
                    zuokuohao1 = rpn(operators, output, str);
                    for (i = 0; i < len1 - 2 * zuokuohao1; i++) {
                        ch2 = output.pop() + ch2;
                    }
                    System.out.println(ch2);
                } else {
                    System.out.println("除数为0");
                }
            } catch (IOException e) {
            }
        }
    
        public static int rpn(Stack<Character> operators, Stack output, String str) {
            char[] chars = str.toCharArray();
            int pre = 0;
            boolean digital;
            int zuokuohao = 0;
            int len = chars.length;
            int bracket = 0;
            for (int i = 0; i < len; ) {
                pre = i;
                digital = Boolean.FALSE;
                while (i < len && !Operator.isOperator(chars[i])) {
                    i++;
                    digital = Boolean.TRUE;
                }
                if (digital) {
                    output.push(str.substring(pre, i));
                } else {
                    char o = chars[i++];
                    if (o == '(') {
                        bracket++;
                        zuokuohao++;
                    }
                    if (bracket > 0) {
                        if (o == ')') {
                            while (!operators.empty()) {
                                char top = operators.pop();
                                if (top == '(') {
                                    break;
                                }
                                output.push(top);
                            }
                            bracket--;
                        } else {
                            while (!operators.empty() && operators.peek() != '(' && Operator.cmp(o, operators.peek()) <= 0) {
                                output.push(operators.pop());
                            }
                            operators.push(o);
                        }
                    } else {
                        while (!operators.empty() && Operator.cmp(o, operators.peek()) <= 0) {
                            output.push(operators.pop());
                        }
                        operators.push(o);
                    }
                }
            }
            while (!operators.empty()) {
                output.push(operators.pop());
            }
            return zuokuohao;
        }
    }
    
    enum Operator {
        ADD('+', 1), SUBTRACT('-', 1),
        MULTIPLY('*', 2), DIVIDE('/', 2),
        LEFT_BRACKET('(', 3), RIGHT_BRACKET(')', 3);
        char value;
        int priority;
    
        Operator(char value, int priority) {
            this.value = value;
            this.priority = priority;
        }
    
        public static int cmp(char c1, char c2) {
            int p1 = 0;
            int p2 = 0;
            for (Operator o : Operator.values()) {
                if (o.value == c1) {
                    p1 = o.priority;
                }
                if (o.value == c2) {
                    p2 = o.priority;
                }
            }
            return p1 - p2;
        }
    
        public static boolean isOperator(char c) {
            for (Operator o : Operator.values()) {
                if (o.value == c) {
                    return true;
                }
            }
            return false;
        }
    }
    
    class chu0 {
        public static int chu0(String s) {
            int i;
            int flag = 0;
            char[] ch = s.toCharArray();
            for (i = 0; i < ch.length; i++) {
                if (ch[i] == '/' && ch[i + 1] == '0') {
                    flag = 1;
                }
            }
            return flag;
        }
    }
    
    
    
    

    MyDC.java

    import java.util.StringTokenizer;
    import java.util.Stack;
    
    public class MyDC {
        /**
         * constant for addition symbol
         */
        private final char ADD = '+';
        /**
         * constant for subtraction symbol
         */
        private final char SUBTRACT = '-';
        /**
         * constant for multiplication symbol
         */
        private final char MULTIPLY = '*';
        /**
         * constant for division symbol
         */
        private final char DIVIDE = '/';
        /**
         * the stack
         */
        private Stack<Integer> stack;
    
        public MyDC() {
            stack = new Stack<Integer>();
        }
    
        public int evaluate(String expr) {
            int op1, op2, result = 0;
            String token;
            StringTokenizer tokenizer = new StringTokenizer(expr);
            while (tokenizer.hasMoreTokens()) {
                token = tokenizer.nextToken();
                //如果是运算符,调用isOperator
                if (isOperator(token)) {
                    //从栈中弹出操作数2
                    op2 = stack.pop();
                    //从栈中弹出操作数1
                    op1 = stack.pop();
                    //根据运算符和两个操作数调用evalSingleOp计算result;
                    result = evalSingleOp(token.charAt(0), op1, op2);
                    //计算result入栈;
                    stack.push(result);
                } else//如果是操作数
                    //操作数入栈;
                    stack.push(Integer.parseInt(token));
            }
    
            return result;
        }
    
        private boolean isOperator(String token) {
            return (token.equals("+") || token.equals("-") ||
                    token.equals("*") || token.equals("/"));
        }
    
        private int evalSingleOp(char operation, int op1, int op2) {
            int result = 0;
    
            switch (operation) {
                case ADD:
                    result = op1 + op2;
                    break;
                case SUBTRACT:
                    result = op1 - op2;
                    break;
                case MULTIPLY:
                    result = op1 * op2;
                    break;
                case DIVIDE:
                    result = op1 / op2;
            }
    
            return result;
        }
    }
    

    MyDCTester.java

    import java.util.Scanner;
    
    public class MyDCTester {
        public static void main(String[] args) {
            String expression, again;
            int result;
            try {
                Scanner in = new Scanner(System.in);
                do {
                    MyDC evaluator = new MyDC();
                    System.out.println("Enter a valid postfix expression: ");
                    expression = in.nextLine();
    
                    result = evaluator.evaluate(expression);
                    System.out.println();
                    System.out.println("That expression equals " + result);
    
                    System.out.print("Evaluate another expression [Y/N]? ");
                    again = in.nextLine();
                    System.out.println();
                }
                while (again.equalsIgnoreCase("y"));
            } catch (Exception IOException) {
                System.out.println("Input exception reported");
            }
        }
    }
    

    实验截图

    任务二要求

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

    实验代码

    对MyBC.java稍做修改

    import java.io.*;
    import java.util.Stack;
    
    public class MyBC {
        public static String transform(String str) {
            int i, f;
            double result;
            int zuokuohao1 = 0;
            String ch2 = new String();
            BufferedReader buf = new BufferedReader(new InputStreamReader(System.in));
            f = chu0.chu0(str);
            if (f == 0) {
                char[] ch1 = str.toCharArray();
                int len1 = ch1.length;
                Stack<Character> operators = new Stack<>();
                Stack output = new Stack<>();
                zuokuohao1 = rpn(operators, output, str);
                for (i = 0; i < len1 - 2 * zuokuohao1; i++) {
                    ch2 = output.pop() +" "+ ch2;
                }
                System.out.println("转换成后缀表达式:"+ ch2);
            } else {
                System.out.println("除数为0");
            }
            return ch2;
        }
    
        public static int rpn(Stack<Character> operators, Stack output, String str) {
            char[] chars = str.toCharArray();
            int pre = 0;
            boolean digital;
            int zuokuohao = 0;
            int len = chars.length;
            int bracket = 0;
            for (int i = 0; i < len; ) {
                pre = i;
                digital = Boolean.FALSE;
                while (i < len && !Operator.isOperator(chars[i])) {
                    i++;
                    digital = Boolean.TRUE;
                }
                if (digital) {
                    output.push(str.substring(pre, i));
                } else {
                    char o = chars[i++];
                    if (o == '(') {
                        bracket++;
                        zuokuohao++;
                    }
                    if (bracket > 0) {
                        if (o == ')') {
                            while (!operators.empty()) {
                                char top = operators.pop();
                                if (top == '(') {
                                    break;
                                }
                                output.push(top);
                            }
                            bracket--;
                        } else {
                            while (!operators.empty() && operators.peek() != '(' && Operator.cmp(o, operators.peek()) <= 0) {
                                output.push(operators.pop());
                            }
                            operators.push(o);
                        }
                    } else {
                        while (!operators.empty() && Operator.cmp(o, operators.peek()) <= 0) {
                            output.push(operators.pop());
                        }
                        operators.push(o);
                    }
                }
            }
            while (!operators.empty()) {
                output.push(operators.pop());
            }
            return zuokuohao;
        }
    }
    
    enum Operator {
        ADD('+', 1), SUBTRACT('-', 1),
        MULTIPLY('*', 2), DIVIDE('/', 2),
        LEFT_BRACKET('(', 3), RIGHT_BRACKET(')', 3);
        char value;
        int priority;
    
        Operator(char value, int priority) {
            this.value = value;
            this.priority = priority;
        }
    
        public static int cmp(char c1, char c2) {
            int p1 = 0;
            int p2 = 0;
            for (Operator o : Operator.values()) {
                if (o.value == c1) {
                    p1 = o.priority;
                }
                if (o.value == c2) {
                    p2 = o.priority;
                }
            }
            return p1 - p2;
        }
    
        public static boolean isOperator(char c) {
            for (Operator o : Operator.values()) {
                if (o.value == c) {
                    return true;
                }
            }
            return false;
        }
    }
    
    class chu0 {
        public static int chu0(String s) {
            int i;
            int flag = 0;
            char[] ch = s.toCharArray();
            for (i = 0; i < ch.length; i++) {
                if (ch[i] == '/' && ch[i + 1] == '0') {
                    flag = 1;
                }
            }
            return flag;
        }
    }
    
    

    Sever2.java

    import java.io.*;
    import java.net.*;
    public class Sever2 {
        public static void main(String[] args) {
            ServerSocket serverForClient = null;
            Socket socketOnServer = null;
            DataOutputStream out = null;
            DataInputStream in = null;
            MyDC myDC = new MyDC();
            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();
                System.out.println("收到后缀表达式:"+suffix);
                out.writeUTF(myDC.evaluate(suffix)+"");
                Thread.sleep(500);
            }catch (Exception e){
                System.out.println("客户已断开"+e);
            }
        }
    }
    

    Client2.java

    import java.io.*;
    import java.net.*;
    import java.util.Scanner;
    import java.util.Stack;
    
    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());
                System.out.println("请输入运算式:");
                String str = inn.nextLine();
                String suffix = MyBC.transform(str);
                out.writeUTF(suffix);
                String result = in.readUTF();
                System.out.println("求值为:"+result);
                Thread.sleep(500);
            }catch (Exception e){
                System.out.println("服务器已断开"+e)#;
            }
        }
    }
    

    实验截图

    任务三要求

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

    实验代码

    Client3.java

    import java.io.*;
    import java.net.*;
    import java.util.Scanner;
    import javax.crypto.Cipher;
    import javax.crypto.KeyGenerator;
    import javax.crypto.SecretKey;
    
    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());
                KeyGenerator kg=KeyGenerator.getInstance("AES");
                kg.init(128);
                SecretKey k=kg.generateKey();
                Cipher cp=Cipher.getInstance("AES");
                cp.init(Cipher.ENCRYPT_MODE,k);
                System.out.println("请输入运算式:");
                String str = inn.nextLine();
                String suffix = MyBC.transform(str);
                byte[]ptext=suffix.getBytes();
                byte[]ctext=cp.doFinal(ptext);
                byte kb[] = k.getEncoded();
                String str1 = Binary.parseByte2HexStr(ctext);
                String str2 = Binary.parseByte2HexStr(kb);
                out.writeUTF(str1);
                out.writeUTF(str2);
                String result = in.readUTF();
                System.out.println("求值为:"+result);
                Thread.sleep(500);
            }catch (Exception e){
                System.out.println("服务器已断开"+e);
            }
        }
    }
    

    Sever3.java

    import java.io.*;
    import java.net.*;
    import javax.crypto.Cipher;
    import javax.crypto.KeyGenerator;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.*;
    public class Sever3 {
        public static void main(String[] args) {
            ServerSocket serverForClient = null;
            Socket socketOnServer = null;
            DataOutputStream out = null;
            DataInputStream in = null;
            MyDC myDC = new MyDC();
            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 str1= in.readUTF();
                byte cipher[] = Binary.parseHexStr2Byte(str1);
                System.out.println("收到密文:"+str1);
                String str2 = in.readUTF();
                byte keyb[] = Binary.parseHexStr2Byte(str2);
                Cipher cp=Cipher.getInstance("AES");
                SecretKeySpec key = new SecretKeySpec(keyb,"AES");
                cp.init(Cipher.DECRYPT_MODE,key);
                byte []ptext=cp.doFinal(cipher);
                String suffix = new String(ptext,"UTF8");
                out.writeUTF(myDC.evaluate(suffix)+"");
                Thread.sleep(500);
            }catch (Exception e){
                System.out.println("客户已断开"+e);
            }
        }
    }
    

    Binary.java

    public class Binary {
        public static String parseByte2HexStr(byte buf[]) {//二进制转换成十六进制
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < buf.length; i++) {
                String hex = Integer.toHexString(buf[i] & 0xFF);
                if (hex.length() == 1) {
                    hex = '0' + hex;
                }
                sb.append(hex.toUpperCase());
            }
            return sb.toString();
        }
        public static byte[] parseHexStr2Byte(String hexStr) {//十六进制转化成二进制
            if (hexStr.length() < 1)
                return null;
            byte[] result = new byte[hexStr.length() / 2];
            for (int i = 0; i < hexStr.length() / 2; i++) {
                int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
                int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
                result[i] = (byte) (high * 16 + low);
            }
            return result;
        }
    }
    

    实验截图

    任务四要求

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

    实验代码

    Client4.java

    import java.io.*;
    import java.net.*;
    import java.security.Key;
    import java.util.Scanner;
    import javax.crypto.Cipher;
    import javax.crypto.KeyGenerator;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.SecretKeySpec;
    
    public class Client4 {
        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("AES");
                kg.init(128);
                SecretKey k=kg.generateKey();
                Cipher cp=Cipher.getInstance("AES");
                cp.init(Cipher.ENCRYPT_MODE,k);
                System.out.println("请输入运算式:");
                String str = inn.nextLine();
                String suffix = MyBC.transform(str);
                byte[]ptext=suffix.getBytes();
                byte[]ctext=cp.doFinal(ptext);
                byte kb[] = k.getEncoded();
                String str1 = Binary.parseByte2HexStr(ctext);
                String str2 = Binary.parseByte2HexStr(kb);
                out.writeUTF(str1);
                out.writeUTF(str2);
                Thread.sleep(500);
    
                Key_DH.createPubAndPriKey("Clientpub.txt","Clientpri.txt");
                FileInputStream fp = new FileInputStream("Clientpub.txt");
                ObjectInputStream bp = new ObjectInputStream(fp);
                Key kp = (Key) bp.readObject();
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                ObjectOutputStream oos = new ObjectOutputStream(baos);
                oos.writeObject(kp);
                byte[] kb1 = baos.toByteArray();
                String PubKey1 = Binary.parseByte2HexStr(kb1);
                out.writeUTF(PubKey1);
                Thread.sleep(500);
    
                String push = in.readUTF();
                byte [] np1= Binary.parseHexStr2Byte(push);
                ObjectInputStream ois = new ObjectInputStream (new ByteArrayInputStream (np1));
                Key k2 = (Key)ois.readObject();;
                FileOutputStream f2 = new FileOutputStream("Serverpub.txt");
                ObjectOutputStream b2 = new ObjectOutputStream(f2);
                b2.writeObject(k2);
                Thread.sleep(500);
    
                SecretKeySpec key = KeyAgre.createKey("Serverpub.txt", "Clientpri.txt");
    
                String result = in.readUTF();
                System.out.println("
    求值为:"+result);
                Thread.sleep(500);
            }catch (Exception e){
                System.out.println("服务器已断开"+e);
            }
        }
    }
    

    Sever4.java

    import java.io.*;
    import java.net.*;
    import java.security.Key;
    import javax.crypto.Cipher;
    import javax.crypto.KeyGenerator;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.*;
    public class Sever4 {
        public static void main(String[] args) {
            ServerSocket serverForClient = null;
            Socket socketOnServer = null;
            DataOutputStream out = null;
            DataInputStream in = null;
            MyDC myDC = new MyDC();
            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 str1= in.readUTF();
                byte cipher[] = Binary.parseHexStr2Byte(str1);
                System.out.println("收到密文:"+str1);
                String str2 = in.readUTF();
                byte keyb[] = Binary.parseHexStr2Byte(str2);
    
                String PubKey = in.readUTF();
                byte np[] = Binary.parseHexStr2Byte(PubKey);
    
                Key_DH.createPubAndPriKey("Serverpub.txt","Serverpri.txt");
    
                FileInputStream fp = new FileInputStream("Serverpub.txt");
                ObjectInputStream bp = new ObjectInputStream(fp);
                Key kp = (Key) bp.readObject();
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                ObjectOutputStream oos = new ObjectOutputStream(baos);
                oos.writeObject(kp);
                byte[] kb = baos.toByteArray();
                String pop = Binary.parseByte2HexStr(kb);
                out.writeUTF(pop);
                Thread.sleep(500);
    
                SecretKeySpec key = KeyAgre.createKey("Serverpub.txt","Clientpri.txt");
    
                Cipher cp=Cipher.getInstance("AES");
                SecretKeySpec key1 = new SecretKeySpec(keyb,"AES");
                cp.init(Cipher.DECRYPT_MODE,key1);
                byte []ptext=cp.doFinal(cipher);
                String suffix = new String(ptext,"UTF8");
                out.writeUTF(myDC.evaluate(suffix)+"");
                Thread.sleep(500);
            }catch (Exception e){
                System.out.println("客户已断开"+e);
            }
        }
    }
    

    Key_DH.java

    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 Key_DH{
        //三个静态变量的定义从
    // C:j2sdk-1_4_0-docdocsguidesecurityjceJCERefGuide.html
    // 拷贝而来
    // The 1024 bit Diffie-Hellman modulus values used by SKIP
        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 createPubAndPriKey(String s1,String s2) 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(s1);
            ObjectOutputStream b1=new  ObjectOutputStream(f1);
            b1.writeObject(pbk);
            // 保存私钥
            FileOutputStream  f2=new FileOutputStream(s2);
            ObjectOutputStream b2=new  ObjectOutputStream(f2);
            b2.writeObject(prk);
        }
    } 
    

    KeyAgre.java

    import java.io.*;
    import java.security.*;
    import javax.crypto.*;
    import javax.crypto.spec.*;
    
    public class KeyAgre{
        public static SecretKeySpec createKey(String s1, String s2) throws Exception{
            // 读取对方的DH公钥
            FileInputStream f1=new FileInputStream(s1);
            ObjectInputStream b1=new ObjectInputStream(f1);
            PublicKey  pbk=(PublicKey)b1.readObject( );
    //读取自己的DH私钥
            FileInputStream f2=new FileInputStream(s2);
            ObjectInputStream b2=new ObjectInputStream(f2);
            PrivateKey  prk=(PrivateKey)b2.readObject( );
            // 执行密钥协定
            KeyAgreement ka=KeyAgreement.getInstance("DH");
            ka.init(prk);
            ka.doPhase(pbk,true);
            //生成共享信息
            System.out.println("共享信息为:");
            byte[] sb=ka.generateSecret();
            for(int i=0;i<sb.length;i++){
                System.out.print(sb[i]+" ");
            }
            SecretKeySpec k=new  SecretKeySpec(sb,"DESede");
            return k;
        }
    } 
    

    实验截图

    任务五要求

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

    实验代码

    Client5.java

    import java.io.*;
    import java.net.*;
    import java.security.Key;
    import java.util.Scanner;
    import javax.crypto.Cipher;
    import javax.crypto.KeyGenerator;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.SecretKeySpec;
    
    public class Client5 {
        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("AES");
                kg.init(128);
                SecretKey k=kg.generateKey();
                Cipher cp=Cipher.getInstance("AES");
                cp.init(Cipher.ENCRYPT_MODE,k);
                System.out.println("请输入运算式:");
                String str = inn.nextLine();
                String suffix = MyBC.transform(str);
                byte[]ptext=suffix.getBytes();
                byte[]ctext=cp.doFinal(ptext);
                byte kb[] = k.getEncoded();
                String str1 = Binary.parseByte2HexStr(ctext);
                String str2 = Binary.parseByte2HexStr(kb);
                out.writeUTF(str1);
                out.writeUTF(str2);
                Thread.sleep(500);
    
                Key_DH.createPubAndPriKey("Clientpub.txt","Clientpri.txt");
                FileInputStream fp = new FileInputStream("Clientpub.txt");
                ObjectInputStream bp = new ObjectInputStream(fp);
                Key kp = (Key) bp.readObject();
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                ObjectOutputStream oos = new ObjectOutputStream(baos);
                oos.writeObject(kp);
                byte[] kb1 = baos.toByteArray();
                String PubKey1 = Binary.parseByte2HexStr(kb1);
                out.writeUTF(PubKey1);
                Thread.sleep(500);
    
                String push = in.readUTF();
                byte [] np1= Binary.parseHexStr2Byte(push);
                ObjectInputStream ois = new ObjectInputStream (new ByteArrayInputStream (np1));
                Key k2 = (Key)ois.readObject();;
                FileOutputStream f2 = new FileOutputStream("Serverpub.txt");
                ObjectOutputStream b2 = new ObjectOutputStream(f2);
                b2.writeObject(k2);
                Thread.sleep(500);
    
                SecretKeySpec key = KeyAgre.createKey("Serverpub.txt", "Clientpri.txt");
    
                String clientMD5 = DigestPass.digestPass(suffix);
                System.out.println("明文MD5值为:"+ clientMD5);
                out.writeUTF(clientMD5);
                Thread.sleep(500);
    
                String result = in.readUTF();
                System.out.println("求值为:"+result);
                Thread.sleep(500);
            }catch (Exception e){
                System.out.println("服务器已断开"+e);
            }
        }
    }
    

    Sever5.java

    import java.io.*;
    import java.net.*;
    import java.security.Key;
    import javax.crypto.Cipher;
    import javax.crypto.KeyGenerator;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.*;
    public class Sever5 {
        public static void main(String[] args) {
            ServerSocket serverForClient = null;
            Socket socketOnServer = null;
            DataOutputStream out = null;
            DataInputStream in = null;
            MyDC myDC = new MyDC();
            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 str1= in.readUTF();
                byte cipher[] = Binary.parseHexStr2Byte(str1);
                System.out.println("收到密文:"+str1);
                String str2 = in.readUTF();
                byte keyb[] = Binary.parseHexStr2Byte(str2);
    
                String PubKey = in.readUTF();
                byte np[] = Binary.parseHexStr2Byte(PubKey);
    
                Key_DH.createPubAndPriKey("Serverpub.txt","Serverpri.txt");
    
                FileInputStream fp = new FileInputStream("Serverpub.txt");
                ObjectInputStream bp = new ObjectInputStream(fp);
                Key kp = (Key) bp.readObject();
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                ObjectOutputStream oos = new ObjectOutputStream(baos);
                oos.writeObject(kp);
                byte[] kb = baos.toByteArray();
                String pop = Binary.parseByte2HexStr(kb);
                out.writeUTF(pop);
                Thread.sleep(500);
    
                SecretKeySpec key = KeyAgre.createKey("Serverpub.txt","Clientpri.txt");
    
                Cipher cp=Cipher.getInstance("AES");
                SecretKeySpec key1 = new SecretKeySpec(keyb,"AES");
                cp.init(Cipher.DECRYPT_MODE,key1);
                byte []ptext=cp.doFinal(cipher);
                String suffix = new String(ptext,"UTF8");
                String serverMD5 = DigestPass.digestPass(suffix);
                System.out.println("解密的MD5值为:"+serverMD5);
                String clientMD5 = in.readUTF();
                if(serverMD5.equals(clientMD5)) {
                    System.out.println("两组MD5值相等");
                    out.writeUTF(myDC.evaluate(suffix) + "");
                }
                Thread.sleep(500);
            }catch (Exception e){
                System.out.println("客户已断开"+e);
            }
        }
    }
    

    DigestPass.java

    import java.security.*;
    public class DigestPass{
        public static String digestPass(String x) throws Exception{
    
            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);
            }
            System.out.println(result);
            return result;
        }
    }
    

    实验截图

  • 相关阅读:
    linux系统telnet端口不通能收到SYN但不回SYN+ACK响应问题排查(转载)
    leveldb
    SSTable and Log Structured Storage: LevelDB
    fio terse输出详解
    bash的循环中无法保存变量
    怎样当好一个师长
    共享变量的并发读写
    Storage Systems topics and related papers
    Storage System and File System Courses
    调试std::string
  • 原文地址:https://www.cnblogs.com/luoleqi/p/10949805.html
Copyright © 2020-2023  润新知