20175208 2018-2019-实验五 网络编程与安全

20175208   实验五 网络编程与安全

实验步骤:

任务一:

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

实验过程

  • 之前结队编程做过一样的题目,所以就肥肠简单啦
  • 为什么要将中缀表达式转为后缀表达式
  • 中缀表达式,虽然符合我们的数学计算习惯,但是并不符合计算机运算的方式
  • 后缀表达式严格按照从左到右进行计算的模式 符合计算机运行方式而中缀表达式需要计算机遇到符号后向后扫描一位 若为括号或优先级更高的操作符还需要向后继续扫描
  • 后缀表达式的定义
  • 后缀表达式(又称为逆波兰reverse polish)就是不需要括号就可以实现调整运算顺序的一种技法。
  • 比如:ab+cde+**,改为中缀表达式其实是(a+b)*((d+e)*c)
  • 后缀表达式不含括号
  • 中缀转后缀
  • 重要的数据结构----栈
  • 如果读入操作数,则直接放入输出字符串;如果读入一般运算符如+-*/,则放入堆栈,但是放入堆栈之前必须要检查栈顶,并确定栈顶运算符的优先级比放入的运算符的优先级低;如果放入的优先级较低,则需要将栈顶的运算符放入输出字符串
  • 如果读入(,因为左括号优先级最高,因此放入栈中,但是注意,当左括号放入栈中后,则优先级最低
  • 如果读入),则将栈中运算符取出放入输出字符串,直到取出(为止,注意:()不输出到输出字符串顺序读完表达式,如果栈中还有操作符,则弹出,并放入输出字符串
  • 后缀表达式的计算
  • 从左到右扫描后缀表达式
  • 如果遇到操作数,将其压入栈中
  • 如果遇到操作符,则从栈中弹出两个操作数,计算结果然后把结果入栈直到遍历完后缀表达式,则计算完成
  • 此时的栈顶元素即为计算结果。

实验代码:

MyBC:

import java.util.*;
import java.lang.String;

public class MyBC {

    private int priority(char c){
        if(c == ‘*‘ || c== ‘/‘)
            return 2;
        else if(c == ‘+‘ || c== ‘-‘)
            return 1;
        else
            return 0;
    }

    private boolean leftPirority(Character c1,char c2){
        if(c1 == null)
            return false;
        return priority(c1)>=priority(c2);
    }
    private boolean isNumber(char c){
        if(‘0‘ <= c && c<=‘9‘)
            return true;
        return false;
    }
    private boolean isLeftBracket(char c){
        if(c == ‘(‘)
            return true;
        return false;
    }
    private boolean isRightBracket(char c){
        if(c == ‘)‘)
            return true;
        return false;
    }
    private boolean isOperator(char c){
        if(c == ‘+‘ || c == ‘-‘ || c == ‘*‘ ||c == ‘/‘)
            return true;
        return false;
    }

    public String parse(String str){
        class Stack<S>{
            private LinkedList<S> list = new LinkedList<S>();

            public void push(S t){
                list.addLast(t);
            }

            public S pop(){
                return list.removeLast();
            }

            public S top(){
                return list.peekLast();
            }

            public boolean isEmpty(){
                return list.isEmpty();
            }
        }

        Stack<Character> stack = new Stack<>();
        StringBuilder string = new StringBuilder();
        char[] cs = str.toCharArray();

        for(int i=0; i<cs.length; ++i){
            char c = cs[i];
            if( isNumber(c)){
                string.append(c);

            }else if( isLeftBracket(c)){
                stack.push(c);

            }else if( isOperator(c)){

                while( leftPirority(stack.top(), c)){
                    string.append( stack.pop());
                }
                stack.push(c);

            }else if( isRightBracket(c)){
                while( !isLeftBracket( stack.top())){
                    string.append(stack.pop());
                }
                stack.pop();
            }
        }

        while( !stack.isEmpty()){
            string.append(stack.pop());
        }

        return string.toString();
    }

}

  MyDC:

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

            if (isOperator(token)) {
                op2 = (stack.pop()).intValue();
                op1 = (stack.pop()).intValue();
                result = evalSingleOp(token.charAt(0), op1, op2);
                stack.push(new Integer(result));
            } else
                stack.push(new Integer(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;
    }
}

  MyBCTester:

import java.util.Scanner;
import java.lang.String;

public class MyBCTester  {

    public static void main (String[] args) {

        String expression, again;

        String result_1;
        int result_2;

        try
        {
            Scanner in = new Scanner(System.in);

            do
            {
                MyBC bc = new MyBC();
                System.out.println ("请输入一个中缀表达式: ");
                expression = in.nextLine();

                result_1 = bc.parse(expression);
                System.out.println();

                String[] b = result_1.split("");
                String x = "";
                for(int i=0;i<b.length;i++){
                    x=x+b[i]+" ";
                }
                System.out.println("后缀表达式为: " + x);

                MyDC dc = new MyDC();
                result_2 = dc.evaluate (x);
                System.out.println ("That expression equals " + result_2);

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

实验代码:

//import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.TextView;

public class MainActivity extends Activity implements
    OnTouchListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView tv = (TextView) findViewById(R.id.textView1);
        tv.setOnTouchListener(this);
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it
// is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }
    @Override
    public boolean onTouch(View arg0, MotionEvent event) {
        Intent intent = new Intent(this, ThirdActivity.class);
        intent.putExtra("message", "20175208Fenix");
        startActivity(intent);
        return true;
    }
}

  实验截图:

任务三:

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

实验代码:

  • gistfile
import javax.crypto.Cipher;
import java.io.*;
import java.net.Socket;
import java.security.Key;
import java.util.Scanner;

public class Client3 {
    public static void main(String args[]) {
        Socket mysocket;
        MyBC mybc = new MyBC();
        DataInputStream in = null;
        DataOutputStream out = null;
        Scanner scanner = new Scanner(System.in);
        String str;
        try {
            mysocket = new Socket("192.168.188.1", 5208);
            in = new DataInputStream(mysocket.getInputStream());
            out = new DataOutputStream(mysocket.getOutputStream());
            System.out.println("客户端启动...");
            FileInputStream f = new FileInputStream("key1.dat");
            ObjectInputStream b = new ObjectInputStream(f);
            Key key = (Key) b.readObject();
            Cipher cp = Cipher.getInstance("DESede");
            cp.init(Cipher.ENCRYPT_MODE, key);
            System.out.println("请输入中缀表达式:");
            str = scanner.nextLine();
            mybc.conversion(str);
            String str1 = mybc.getMessage();
            byte ptext[] = str1.getBytes("UTF-8");
            byte ctext[] = cp.doFinal(ptext);
            System.out.println("被加密的后缀表达式:");
            for (int i = 0; i < ctext.length; i++) {
                System.out.print(ctext[i] + ",");
            }
            System.out.println("");
            out.writeUTF(ctext.length + "");
            for (int i = 0; i < ctext.length; i++) {
                out.writeUTF(ctext[i] + "");
                //System.out.print();
            }
            String s = in.readUTF();   //in读取信息,堵塞状态
            System.out.println("客户收到服务器的回应:" + s);
        } catch (Exception e) {
            System.out.println("服务器已断开" + e);
        }
    }
}
  • SDec
import java.io.*;
import javax.crypto.*;
import javax.crypto.spec.*;

public class SDec {
    public static String decipher(String s) throws Exception {
        // 获取密文
        FileInputStream f = new FileInputStream("SEnc.dat");
        int num = f.available();
        byte[] ctext = new byte[num];
        f.read(ctext);
        // 获取密钥
        FileInputStream f2 = new FileInputStream("keykb1.dat");
        int num2 = f2.available();
        byte[] keykb = new byte[num2];
        f2.read(keykb);
        SecretKeySpec k = new SecretKeySpec(keykb, "DESede");
        // 解密
        Cipher cp = Cipher.getInstance("DESede");
        cp.init(Cipher.DECRYPT_MODE, k);
        byte[] ptext = cp.doFinal(ctext);
        // 显示明文
        String p = new String(ptext, "UTF8");
        System.out.println(p);
        return p;
    }
}
  • SEnc
import javax.crypto.Cipher;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.security.Key;

public class SEnc {
    public String Cipher(String s) throws Exception {
        FileInputStream f = new FileInputStream("key1.dat");
        ObjectInputStream b = new ObjectInputStream(f);
        Key k = (Key) b.readObject();
        Cipher cp = Cipher.getInstance("DESede");
        cp.init(Cipher.ENCRYPT_MODE, k);
        byte ptext[] = s.getBytes("UTF8");
        System.out.println("密文为:");
        for (int i = 0; i < ptext.length; i++) {
            System.out.print(ptext[i] + ",");
        }
        System.out.println("");
        byte ctext[] = cp.doFinal(ptext);
        String cipher = "";
        for (int i = 0; i < ctext.length; i++) {
            cipher = cipher + ctext[i];
        }
        FileOutputStream f2 = new FileOutputStream("SEnc.dat");
        f2.write(ctext);
        return cipher;
    }
}
  • Server3
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class Server3 {
    public static void main(String args[]) {
        MyDC mydc = new MyDC();
        ServerSocket serverForClient = null;
        Socket socketOnServer = null;
        DataOutputStream out = null;
        DataInputStream in = null;
        try {
            serverForClient = new ServerSocket(5208);
        } catch (IOException e1) {
            System.out.println(e1);
        }
        try {
            System.out.println("等待客户呼叫");
            socketOnServer = serverForClient.accept(); //堵塞状态,除非有客户呼叫
            System.out.println("客户已连接");
            out = new DataOutputStream(socketOnServer.getOutputStream());
            in = new DataInputStream(socketOnServer.getInputStream());
            String leng = in.readUTF(); // in读取信息,堵塞状态
            byte ctext[] = new byte[Integer.parseInt(leng)];
            for (int i = 0;i<Integer.parseInt(leng);i++) {
                String temp = in.readUTF();
                ctext[i] = Byte.parseByte(temp);
            }
            // 获取密钥
            FileInputStream f2 = new FileInputStream("keykb1.dat");
            int num2 = f2.available();
            byte[] keykb = new byte[num2];
            f2.read(keykb);
            SecretKeySpec k = new SecretKeySpec(keykb, "DESede");
            // 解密
            Cipher cp = Cipher.getInstance("DESede");
            cp.init(Cipher.DECRYPT_MODE, k);
            byte[] ptext = cp.doFinal(ctext);
            /*for (int i = 0; i < ptext.length; i++) {
                System.out.print(ptext[i] + ",");
            }
            */
            System.out.println("");
            // 显示明文
            String p = new String(ptext,"UTF8");
            System.out.println("被解密的后缀表达式:" + p);
            System.out.println("计算后缀表达式" + p);
            out.writeUTF(mydc.evaluate(p)+"");
        } catch (Exception e) {
            System.out.println("客户已断开" + e);
        }
    }
}

  实验截图:

任务四:

  • Client4
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.net.Socket;
import java.security.Key;
import java.util.Optional;
import java.util.Scanner;

public class Client4 {
    public static void main(String args[]) {
        MyBC mybc = new MyBC();
        Socket mysocket;
        DataInputStream in = null;
        DataOutputStream out = null;
        Scanner scanner = new Scanner(System.in);
        String str;
        try {
            mysocket = new Socket("192.168.188.1", 5208);
            System.out.println("客户端启动...");
            in = new DataInputStream(mysocket.getInputStream());
            out = new DataOutputStream(mysocket.getOutputStream());
            System.out.println("请输入中缀表达式:");
            str = scanner.nextLine();

            Key_DH.DH("Cpub.dat","Cpri.dat");
            FileInputStream fp = new FileInputStream("Cpub.dat");
            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();
            out.writeUTF(kb.length + "");
            for (int i = 0; i < kb.length; i++) {
                out.writeUTF(kb[i] + "");
            }
            Thread.sleep(1000);
            int len = Integer.parseInt(in.readUTF());
            byte np[] = new byte[len];
            for (int i = 0;i<len;i++) {
                String temp = in.readUTF();
                np[i] = Byte.parseByte(temp);
            }
            ObjectInputStream ois = new ObjectInputStream (new ByteArrayInputStream (np));
            Key k2 = (Key)ois.readObject();;
            FileOutputStream f2 = new FileOutputStream("Spub.dat");
            ObjectOutputStream b2 = new ObjectOutputStream(f2);
            b2.writeObject(k2);

            KeyAgree.DH("Spub.dat","Cpri.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("");
            SecretKeySpec k = new SecretKeySpec(keysb, "DESede");
            Cipher cp = Cipher.getInstance("DESede");
            cp.init(Cipher.ENCRYPT_MODE, k);
            mybc.conversion(str);
            String str1 = mybc.getMessage();
            byte ptext[] = str1.getBytes("UTF-8");
            byte ctext[] = cp.doFinal(ptext);
            System.out.println("后缀表达式已被加密:");
            for (int i = 0; i < ctext.length; i++) {
                System.out.print(ctext[i] + ",");
            }
            System.out.println("");
            out.writeUTF(ctext.length + "");
            for (int i = 0; i < ctext.length; i++) {
                out.writeUTF(ctext[i] + "");
            }
            String s = in.readUTF();   //in读取信息,堵塞状态
            System.out.println("客户收到服务器的回应:" + s);
        } catch (Exception e) {
            System.out.println("服务器已断开" + e);
        }
    }
}
  •   KeyAgree
import javax.crypto.KeyAgreement;
import javax.crypto.spec.SecretKeySpec;
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 DH(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);
        //生成共享信息
        byte[ ] sb=ka.generateSecret();
        FileOutputStream fsb = new FileOutputStream("sb.dat");
        fsb.write(sb);
    }
}
  •   Key_DH
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 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);
    }
}
  •   Server4
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.Key;

public class Server4 {
    public static void main(String args[]) {
        MyDC mydc = new MyDC();
        ServerSocket serverForClient = null;
        Socket socketOnServer = null;
        DataOutputStream out = null;
        DataInputStream in = null;
        try {
            serverForClient = new ServerSocket(5318);
        } catch (IOException e1) {
            System.out.println(e1);
        }
        try {
            System.out.println("等待客户呼叫");
            socketOnServer = serverForClient.accept(); //堵塞状态,除非有客户呼叫
            System.out.println("客户已连接");
            out = new DataOutputStream(socketOnServer.getOutputStream());
            in = new DataInputStream(socketOnServer.getInputStream());

            Key_DH.DH("Spub.dat","Spri.dat");
            int len = Integer.parseInt(in.readUTF());
            byte np[] = new byte[len];
            for (int i = 0;i<len;i++) {
                String temp = in.readUTF();
                np[i] = Byte.parseByte(temp);
            }
            ObjectInputStream ois = new ObjectInputStream (new ByteArrayInputStream (np));
            Key k2 = (Key)ois.readObject();;
            FileOutputStream f2 = new FileOutputStream("Cpub.dat");
            ObjectOutputStream b2 = new ObjectOutputStream(f2);
            b2.writeObject(k2);

            FileInputStream fp = new FileInputStream("Spub.dat");
            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();
            out.writeUTF(kb.length + "");
            for (int i = 0; i < kb.length; i++) {
                out.writeUTF(kb[i] + "");
            }

            KeyAgree.DH("Cpub.dat","Spri.dat");

            String leng = in.readUTF(); // in读取信息,堵塞状态
            byte ctext[] = new byte[Integer.parseInt(leng)];
            for (int i = 0;i<Integer.parseInt(leng);i++) {
                String temp = in.readUTF();
                ctext[i] = Byte.parseByte(temp);
            }
            // 获取密钥
            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("");
            SecretKeySpec k = new SecretKeySpec(keysb, "DESede");
            // 解密
            Cipher cp = Cipher.getInstance("DESede");
            cp.init(Cipher.DECRYPT_MODE, k);
            byte[] ptext = cp.doFinal(ctext);
            System.out.println("");
            // 显示明文
            String p = new String(ptext,"UTF8");
            System.out.println("被解密的后缀表达式:" + p);
            System.out.println("计算后缀表达式" + p);
            out.writeUTF(mydc.evaluate(p)+"");
        } catch (Exception e) {
            System.out.println("客户已断开" + e);
        }
    }
}

  实验截图:

任务五:

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

实验代码:

  • Client5
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 Client5 {
    public static void main(String args[]) {
        MyBC mybc = new MyBC();
        Socket mysocket;
        DataInputStream in = null;
        DataOutputStream out = null;
        Scanner scanner = new Scanner(System.in);
        String str;
        try {
            mysocket = new Socket("192.168.188.1", 5208);
            System.out.println("客户端启动...");
            in = new DataInputStream(mysocket.getInputStream());
            out = new DataOutputStream(mysocket.getOutputStream());
            System.out.println("请输入中缀表达式:");
            str = scanner.nextLine();

            Key_DH.DH("Cpub.dat","Cpri.dat");
            FileInputStream fp = new FileInputStream("Cpub.dat");
            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();
            out.writeUTF(kb.length + "");
            for (int i = 0; i < kb.length; i++) {
                out.writeUTF(kb[i] + "");
            }
            Thread.sleep(500);
            int len = Integer.parseInt(in.readUTF());
            byte np[] = new byte[len];
            for (int i = 0;i<len;i++) {
                String temp = in.readUTF();
                np[i] = Byte.parseByte(temp);
            }
            ObjectInputStream ois = new ObjectInputStream (new ByteArrayInputStream (np));
            Key k2 = (Key)ois.readObject();;
            FileOutputStream f2 = new FileOutputStream("Spub.dat");
            ObjectOutputStream b2 = new ObjectOutputStream(f2);
            b2.writeObject(k2);

            KeyAgree.DH("Spub.dat","Cpri.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("");
            SecretKeySpec k = new SecretKeySpec(keysb, "DESede");
            Cipher cp = Cipher.getInstance("DESede");
            cp.init(Cipher.ENCRYPT_MODE, k);

            mybc.conversion(str);
            String str1 = mybc.getMessage();
            byte ptext[] = str1.getBytes("UTF-8");
            String ptextMd5 = DigestPass.DP(str1);
            System.out.println("明文的MD5值:"+ptextMd5);
            byte ctext[] = cp.doFinal(ptext);
            System.out.println("被加密的后缀表达式:");
            for (int i = 0; i < ctext.length; i++) {
                System.out.print(ctext[i] + ",");
            }
            System.out.println("");
            out.writeUTF(ctext.length + "");
            for (int i = 0; i < ctext.length; i++) {
                out.writeUTF(ctext[i] + "");
            }
            out.writeUTF(ptextMd5);
            String s = in.readUTF();   //in读取信息,堵塞状态
            System.out.println("客户收到服务器的回应:" + s);
        } catch (Exception e) {
            System.out.println("服务器已断开" + e);
        }
    }
}
  • Server5
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 Server5 {
    public static void main(String args[]) {
        MyDC mydc = new MyDC();
        ServerSocket serverForClient = null;
        Socket socketOnServer = null;
        DataOutputStream out = null;
        DataInputStream in = null;
        try {
            serverForClient = new ServerSocket(5318);
        } catch (IOException e1) {
            System.out.println(e1);
        }
        try {
            System.out.println("等待客户呼叫");
            socketOnServer = serverForClient.accept(); //堵塞状态,除非有客户呼叫
            System.out.println("客户已连接");
            out = new DataOutputStream(socketOnServer.getOutputStream());
            in = new DataInputStream(socketOnServer.getInputStream());

            Key_DH.DH("Spub.dat","Spri.dat");
            int len = Integer.parseInt(in.readUTF());
            byte np[] = new byte[len];
            for (int i = 0;i<len;i++) {
                String temp = in.readUTF();
                np[i] = Byte.parseByte(temp);
            }
            ObjectInputStream ois = new ObjectInputStream (new ByteArrayInputStream(np));
            Key k2 = (Key)ois.readObject();;
            FileOutputStream f2 = new FileOutputStream("Cpub.dat");
            ObjectOutputStream b2 = new ObjectOutputStream(f2);
            b2.writeObject(k2);

            FileInputStream fp = new FileInputStream("Spub.dat");
            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();
            out.writeUTF(kb.length + "");
            for (int i = 0; i < kb.length; i++) {
                out.writeUTF(kb[i] + "");
            }

            KeyAgree.DH("Cpub.dat","Spri.dat");

            String leng = in.readUTF(); // in读取信息,堵塞状态
            byte ctext[] = new byte[Integer.parseInt(leng)];
            for (int i = 0;i<Integer.parseInt(leng);i++) {
                String temp = in.readUTF();
                ctext[i] = Byte.parseByte(temp);
            }
            String check = in.readUTF();
            // 获取密钥
            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("");
            SecretKeySpec k = new SecretKeySpec(keysb, "DESede");
            // 解密
            Cipher cp = Cipher.getInstance("DESede");
            cp.init(Cipher.DECRYPT_MODE, k);
            byte[] ptext = cp.doFinal(ctext);
            System.out.println("");
            // 显示明文
            String p = new String(ptext, "UTF8");
            String pMd5 = DigestPass.DP(p);
            System.out.println("被解密明文的MD5值:"+pMd5);
            if (pMd5.equals(check)){
                System.out.println("和客户端的MD5值一致");
                System.out.println("计算后缀表达式" + p);
                out.writeUTF(mydc.evaluate(p)+"");
            }
            else {
                System.out.println("警告:和客户端的MD5值不一致!");
            }
        } catch (Exception e) {
            System.out.println("客户已断开" + e);
        }
    }
}

  实验截图:

码云连接https://gitee.com/zhangjiahua20175208/codes

实验感悟:

本次实验考察的是网络编程与安全,基于四则运算来进行的,与以前进行的实验有相同部分,可以参考以前的代码,所以这次实验并不是很困难。两人结对的方式也让实验可以互帮互助,减轻实验的压力,客服端/服务器功能在学习的时候并不是很牢固,通过这次的实验,在应用上有了更好地掌握。

原文地址:https://www.cnblogs.com/kaoru/p/10962838.html

时间: 2024-11-10 14:26:51

20175208 2018-2019-实验五 网络编程与安全的相关文章

20165223 实验五 网络编程与安全

实验五 网络编程与安全 目录 一.实验报告封面 二.具体实验内容 (一)网络编程与安全-1 (二)网络编程与安全-2 (三)网络编程与安全-3 (四)网络编程与安全-4 (五)网络编程与安全-5 三.实验总结 四.PSP时间 一.实验报告封面 北京电子科技学院(BESTI) 实 验 报 告 ◆ ◇ ◆ ◇ 课程 Java程序设计 班级 1652班 姓名 蔡霓 学号 20165223 成绩 指导教师 娄嘉鹏 实验日期 2018年5月28日 实验密级 非密级 预习程度 已预习 实验时间 13:45

20165332实验五 网络编程与安全

20165332实验五 网络编程与安全 实验报告封面 课程:Java程序设计 班级:1653 姓名:延亿卓 学号:20165332 指导教师:娄嘉鹏 实验日期:2018.5.28 实验时间:15:25 - 17:15 实验序号:五 实验名称:网络编程与安全 实验目的 1.了解计算机网络基础 2.掌握JavaSocket编程 3.理解混合密码系统 4.掌握Java密码技术相关API的使用 一.网络编程与安全-1 实验要求: 参考http://www.cnblogs.com/rocedu/p/676

实验五 网络编程与安全

20165225 实验五 网络编程与安全 实验报告封面: 课程:Java程序设计 班级:1652班 姓名:王高源 学号:20165225 指导教师:娄嘉鹏 实验日期:2018年5月14日 实验时间:3:35 - 5:15 实验序号:实验5 实验名称:网络编程与安全 实验内容: 1.掌握Java Socket的相关内容: 2.学会建立客户端与服务器端之间的联系: 3.学习并应用密码学的相关内容 严禁抄袭,有该行为者实验成绩归零,并附加其他惩罚措施. 网络编程与安全一: 实验要求: 两人一组结对编程

实验五 网络编程及安全

实验五 网络编程与安全 一.实验内容: 1.运行教材上TCP代码,结对进行,一人服务器,一人客户端: 2.利用加解密代码包,编译运行代码,一人加密,一人解密: 3.集成代码,一人加密后通过TCP发送: 注:加密使用AES或者DES/AES或者DES加密密钥key并发送,使用服务器的公钥加密/公钥算法使用RSA或DH/检验发送信息的完整性使用MD5或者SHA3: 4.用Git进行版本控制. 5.完成Blog 二.实验步骤: 1.首先建立一个Socket对象,用来连接特定服务器的指定端口,输入的参数

20155208徐子涵 实验五 网络编程与安全

20155208徐子涵 实验五 网络编程与安全 实验一 两人一组结对编程: 参考http://www.cnblogs.com/rocedu/p/6766748.html#SECDSA 结对实现中缀表达式转后缀表达式的功能 MyBC.java 结对实现从上面功能中获取的表达式中实现后缀表达式求值的功能,调用MyDC.java 上传测试代码运行结果截图和码云链接 产品代码 1 import java.util.StringTokenizer; 2 import java.util.Stack; 3

20165334 实验五 网络编程与安全

20165334 实验五 网络编程与安全 任务1 结对实现中缀表达式转后缀表达式的功能 MyBC.java 结对实现从上面功能中获取的表达式中实现后缀表达式求值的功能,调用MyDC.java 上传测试代码运行结果截图和码云链接 1.中缀变后缀思路分析 设置一个运算符栈,设置一个后缀表达式字符串: 从左到右依次对中缀表达式中的每个字符x分别进行以下处理,直至表达式结束: ?? - 若x是左括号'(',将其入栈: ??- 若x是数字,将其后连续若干数字添加到后缀表达式字符串之后,并添加空格作为分隔符

20165329 实验五 网络编程与安全

20165329 实验五 网络编程与安全 实验目的 1.了解计算机网络基础 2.掌握JavaSocket编程 3.理解混合密码系统 4.掌握Java密码技术相关API的使用 实验内容 任务一 内容:编程实现中缀表达式转后缀表达式的功能 MyBC.java,并实现从上面功能中获取的表达式中实现后缀表达式求值的功能,调用MyDC.java 代码链接 运行截图如下: 任务二 内容: 1.基于Java Socket实现客户端/服务器功能,传输方式用TCP 2.客户端让用户输入中缀表达式,然后把中缀表达式

20165321 实验五 网络编程与安全

任务1 任务详情 两人一组结对编程: 参考http://www.cnblogs.com/rocedu/p/6766748.html#SECDSA 结对实现中缀表达式转后缀表达式的功能 MyBC.java 结对实现从上面功能中获取的表达式中实现后缀表达式求值的功能,调用MyDC.java 上传测试代码运行结果截图和码云链接 代码 由于myDC.java与myBC.java都不是主类,没有办法运行,所以只有上代码了. myDC.java import java.util.*; public clas

20165339 实验五 网络编程与安全

实验五<网络编程与安全>实验报告 实验五 网络编程与安全-1 两人一组结对编程: 0.参考http://www.cnblogs.com/rocedu/p/6766748.html#SECDSA 1 结对实现中缀表达式转后缀表达式的功能 MyBC.java 2.结对实现从上面功能中获取的表达式中实现后缀表达式求值的功能,调用MyDC.java 3 上传测试代码运行结果截图和码云链接 知识点 Exp = a * b + (c - d / e) * f 前缀式: + * a b * - c / d

20165305 实验五 网络编程与安全

实验五-1 两人一组结对编程: 参考http://www.cnblogs.com/rocedu/p/6766748.html#SECDSA 结对实现中缀表达式转后缀表达式的功能 MyBC.java 结对实现从上面功能中获取的表达式中实现后缀表达式求值的功能,调用MyDC.java 上传测试代码运行结果截图和码云链接 实验五-2 结对编程:1人负责客户端,一人负责服务器 注意责任归宿,要会通过测试证明自己没有问题 基于Java Socket实现客户端/服务器功能,传输方式用TCP 客户端让用户输入