2018-2019-20175329実験ファイブ「ネットワークプログラミングおよびセキュリティ」テストレポート

2018-2019-20175329実験ファイブ「ネットワークプログラミングおよびセキュリティ」テストレポート

実験手順

タスク

  • ペアプログラミングのペア
  • ジャンクション機能MyBC.java実現中置表現転送後置式
  • 一対MyDC.javaコール、後置表現の機能を達成するために、上記の機能から得られた発現を達成
    実験
  • プログラミングチームは、同じ結び目トピックを行っているので、シンプルなスープです前に
  • なぜ、後置記法に式を中置必要があります
  • 中置式、私たちの数学の習慣に沿ってではなく、コンピュータの仕方一貫した操作であるが
  • コンピュータのオペレーティングモードと中置式の計算に厳密に準拠して左から右へのPostfix発現パターンブラケットのシンボルに遭遇した後に逆方向にスキャンするコンピュータを必要とするか、またはより高い優先順位の演算子も後方にスキャンし続ける必要がある場合
  • 後置式の定義
  • ポストフィックス表記は、(また、逆ポーランド逆ポリッシュと呼ばれる)技術のほんの一種類である操作の順序を達成することができる調整するブラケットを必要としません。
  • たとえば:ab+cde+**代わりに中置式は、実際にあります(a+b)*((d+e)*c)
  • 括弧なしでPostfixの式
  • 中置ターンサフィックス
  • 重要なデータ構造----スタック
  • 読み取り動作の数は、出力文字列に直接配置されている場合は、船舶事業者+として読み込む場合 - * /スタックに、しかし、スタックにスタックする前にチェックインする必要があり、スタックが決定され、演算子の優先順位演算子よりも低い優先度にステージ、低い優先度に置かれた場合、出力文字列オペレータに積層する必要があります
  • あなたは左括弧は、最も高い優先度を有しているため、スタック上に置かれているため(読まなく、括弧を去ったとき、スタックの上に置かれていることに注意している場合、最も低い優先度
  • )読めば削除されるまで、スタックは、これまでのところ(出力文字列演算子に取得されます:(注意)オペレータスタック、ポップアップがある場合には、出力文字列発現配列に読み出されていません、そして、出力文字列に配置されました
  • Postfixの発現コンピューティング
  • 左から右のスキャン後置式へ
  • あなたはスタックにプッシュされたオペランドを、発生した場合
  • スタックのポップからオペレータ出会い、2つのオペランドの計算結果と結果のpostfixのスタックを横断してまでならば、計算が完了しています
  • このとき、先頭の要素は計算結果です。
  • テストコード
/* creat by xyw,cyy
*/
import java.util.Stack;

public class MyBC {
    MyBC(){}
    public static String infixToSuffix(String exp){
        Stack<String> s = new Stack<String>();         // 创建操作符堆栈
        String suffix = "";            // 要输出的后缀表达式字符串
        String suffix1 = "";             //上一次的后缀表达式
        String suffix2 = "";
        String str[] = exp.split(" ");
        int length = str.length; // 输入的中缀表达式的长度
        String temp="";
        for (int i = 0; i < length; i++) {            // 对该中缀表达式的每一个字符并进行判断
            switch (str[i]) {
                case " ":break;           // 忽略空格
                case "(":
                    s.push(str[i]);                  // 如果是左括号直接压入堆栈
                    break;
                case "+":
                case "-":
                    if(s.size() != 0){          // 碰到'+' '-',将栈中的所有运算符全部弹出去,直至碰到左括号为止,输出到队列中去
                        temp = s.pop();
                        if (temp.equals("(")) {     // 将左括号放回堆栈,终止循环
                            s.push(temp);
                            s.push(str[i]);
                            break;
                        }
                        else{
                            s.push(str[i]);
                            suffix2 = suffix2 + temp + " ";
                            break;
                        }
                    }
                    else{
                        s.push(str[i]);      // 说明是当前为第一次进入或者其他前面运算都有括号等情况导致栈已经为空,此时需要将符号进栈
                        break;
                    }
                    // 如果是乘号或者除号,则弹出所有序列,直到碰到加好、减号、左括号为止,最后将该操作符压入堆栈
                case "*":
                case "÷":
                    if(s.size()!=0){
                        temp = s.pop();
                        if(temp.equals("+")||temp.equals("-")||temp.equals("(")){
                            s.push(temp);
                            s.push(str[i]);
                            break;
                        }
                        else{
                            s.push(str[i]);
                            suffix2 = suffix2+temp+" ";
                            break;
                        }
                    }
                    else {
                        s.push(str[i]);     //当前为第一次进入或者其他前面运算都有括号等情况导致栈已经为空,此时需要将符号进栈
                        break;
                    }
                    // 如果碰到的是右括号,则距离栈顶的第一个左括号上面的所有运算符弹出栈并抛弃左括号
                case ")":
                    while (!s.isEmpty()) {
                        temp = s.pop();
                        if (temp.equals("(")) {
                            break;
                        } else {
                            suffix2 = suffix2+temp+" ";
                        }
                    }
                    break;
                // 默认情况,如果读取到的是数字,则直接送至输出序列
                default:
                    suffix2 = suffix2+str[i]+" ";
                    break;
            }

        }
        // 如果堆栈不为空,则把剩余运算符一次弹出,送至输出序列
        while (s.size() != 0) {
            suffix2 = suffix2+s.pop()+" ";
        }
        if(suffix1.equals("")){          //第一个题目
            suffix1 = suffix2;
            suffix = suffix2;
        }
        else{
            if(suffix2.equals(suffix1))
                suffix = "";
            else
                suffix = suffix2;
        }
        suffix1 = suffix2;
        return suffix;
    }
}
  • スクリーンショット実験

  • タスクII
  • ペアプログラミング:クライアントの担当1人、サーバーの担当者
  • その責任の先に注意してください、我々は彼が質問しなかったことを証明するための試験に合格します
  • Javaのソケットは、TCPを使用して、送信をクライアント/サーバーベースの機能を実装します
  • 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式通过网络发送给服务器
  • 服务器接收到后缀表达式,调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
  • 客户端显示服务器发送过来的结果
  • 实验代码
    服务器
import java.io.*;
import java.net.*;
public class Server {
    public static void main(String args[]) {
        int answer;
        ServerSocket serverForClient=null;
        Socket socketOnServer=null;
        DataOutputStream out=null;
        DataInputStream  in=null;
        try { serverForClient = new ServerSocket(2010);
        }
        catch(IOException e1) {
            System.out.println(e1);
        }
        try{ System.out.println("等待客户呼叫");
            socketOnServer = serverForClient.accept(); //堵塞状态,除非有客户呼叫
            out=new DataOutputStream(socketOnServer.getOutputStream());
            in=new DataInputStream(socketOnServer.getInputStream());
            String s=in.readUTF(); // in读取信息,堵塞状态
            System.out.println("服务器收到客户的提问:"+s);
            MyDC d=new MyDC();
            answer=d.evaluate(s);
            out.writeUTF(answer+"");
            Thread.sleep(500);
        }
        catch(Exception e) {
            System.out.println("客户已断开"+e);
        }
    }
}
**客户端**
import java.io.*;
import java.net.*;
import java.lang.*;
import java.util.Scanner;

public class Client {
    public static void main(String args[]) {
        Socket mysocket;
        DataInputStream in=null;
        DataOutputStream out=null;
        try{  mysocket=new Socket("127.1.0.0",2010);
            in=new DataInputStream(mysocket.getInputStream());
            out=new DataOutputStream(mysocket.getOutputStream());
            System.out.println("请输入算式:");
            Scanner scanner=new Scanner(System.in);
            String str=scanner.nextLine();
            MyBC b=new MyBC();
            str=b.result(str);
            out.writeUTF(str);
            String  s=in.readUTF();   //in读取信息,堵塞状态
            System.out.println("客户收到服务器的回答:"+s);
            Thread.sleep(500);
        }
        catch(Exception e) {
            System.out.println("服务器已断开"+e);
        }
    }
}
  • 实验过程
  • 使用java.net.Socket对象来表示一个套接字
  • 使用Socket的构造方法创建套接字,如:public Socket(java.lang.String host, int port)。其中,host是远程机器名或IP地址,port是端口号,IP地址查询方法如下:
  • 调用Socket类的getOutputStream方法来获取一个java.io.OutputStream对象。要向远程应用程序发送文本,通常要从返回的OutputStream对象构建一个java.io.PrintWriter对象。要接收来自连接的另一端的字节流
  • 调用Socket类的getInputStream方法,它返回一个java.io.InputStream
  • ServerSocket是服务器套接字的一个实现,一旦服务器套接字获得了一个连接请求,它就会创建一个Socket实例
  • 任务截图


    任务三
  • 加密结对编程:1人负责客户端,一人负责服务器
  • 注意责任归宿,要会通过测试证明自己没有问题
  • 基于Java Socket实现客户端/服务器功能,传输方式用TCP
  • 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用DES或AES算法加密后通过网络把密文发送给服务器
  • 服务器接收到后缀表达式表达式后,进行解密(和客户端协商密钥,可以用数组保存),然后调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
  • 客户端显示服务器发送过来的结果
    实验原理
    本部分需要参考Java密码学算法中“Java对称加密-DES算法”部分的内容,不同的是我和伙伴没有通过对象序列化方式写入文件中,而是直接将密钥进行传递,具体过程如下:
  • 客户端
  • 获取密钥生成器KeyGenerator kg=KeyGenerator.getInstance("DESede")
  • 初始化密钥生成器kg.init(168);
  • 生成密钥SecretKey k=kg.generateKey( );
  • 获取主要编码格式byte[ ] kb=k.getEncoded( );
  • 传送密钥长度及密钥内容
  • 创建密码器Cipher cp=Cipher.getInstance("DESede");
  • 初始化密码器cp.init(Cipher.ENCRYPT_MODE, k);
  • 获取等待加密的明文byte ptext[]=s.getBytes("UTF8");
  • 执行加密byte []ptext=cp.doFinal(ctext)
  • 服务器
  • 接收密钥长度
  • 接收密钥内容
  • 创建密码器Cipher cp=Cipher.getInstance("DESede");
  • 初始化密码器cp.init(Cipher.DECRYPT_MODE, k);
  • 执行解密byte []ptext=cp.doFinal(ctext)
  • 实验代码
    客户端
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.io.*;
import java.net.*;
import java.util.Scanner;

public class Client1 {
    public static void main(String[] args) {
        Scanner inn = new Scanner(System.in);
        Socket mysocket;
        DataInputStream in = null;
        DataOutputStream out = null;
        try{
            mysocket = new Socket("127.0.0.1",2010);
            in = new DataInputStream(mysocket.getInputStream());
            out = new DataOutputStream(mysocket.getOutputStream());
            KeyGenerator kg=KeyGenerator.getInstance("DESede");
            kg.init(168);
            SecretKey k=kg.generateKey( );
            byte[ ] kb=k.getEncoded( );
            out.writeUTF(kb.length+"");
            for(int i=0; i<kb.length; i++){
                out.writeUTF(kb[i]+"");
            }
            System.out.println("请输入中缀表达式:");
            String infix = inn.nextLine();
            MyBC myBC = new MyBC();
            String suffix = myBC.infixToSuffix(infix);
            Cipher cp=Cipher.getInstance("DESede");
            cp.init(Cipher.ENCRYPT_MODE, k);
            byte ptext[]=suffix.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);
        }
    }
}
服务器
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.net.*;
public class Sever1 {
    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 e1){
            System.out.println("请客户端回复"+e1);
        }
        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)];
            for(int i=0; i<Integer.parseInt(keylength); i++){
                String t = in.readUTF();
                kb[i] = Byte.parseByte(t);
            }
            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);
            }
            SecretKeySpec k=new  SecretKeySpec(kb,"DESede");
            Cipher cp=Cipher.getInstance("DESede");
            cp.init(Cipher.DECRYPT_MODE, k);
            byte []ptext=cp.doFinal(ctext);
            String suffix = new String(ptext,"UTF8");
            System.out.println("请提问"+suffix);
            out.writeUTF(myDC.evaluate(suffix)+"");
            Thread.sleep(500);
        }catch (Exception e){
            System.out.println("已断开连接");
        }
    }
}

实验截图

4.任务四

  • 基于Java Socket实现客户端/服务器功能,传输方式用TCP
  • 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加密通过网络把密文发送给服务器
  • 客户端和服务器用DH算法进行3DES或AES算法的密钥交换
  • 服务器接收到后缀表达式表达式后,进行解密,然后调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
  • 客户端显示服务器发送过来的结果
  • 上传测试结果截图和码云链接
  • 实验原理
  • 本部分需要参考Java密码学算法中“使用密钥协定创建共享密钥”部分的内容,对博客中的代码进行了部分更改如下:
    Key_DHKeyAgree主类的参数改为由客户端和服务器传递,并修改方法名
    public static void DH(String str1,String str2) throws Exception
    public static void Agree(String str1,String str2)
  • 客户端和服务器分别产生自己的公钥和私钥,并用过字节数组的形式分别向另一方传递自己的公钥;
  • 客户端和服务器接受对方的公钥后利用自己的私钥创建共享密钥
  • 创建密钥协定对象KeyAgreement ka=KeyAgreement.getInstance("DH");
  • 初始化密钥协定对象ka.init(prk);
  • 执行密钥协定ka.doPhase(pbk,true);
  • 生成共享信息byte[ ] sb=ka.generateSecret();
  • 从文件中读取信息并给出共享密钥
    实验代码
  • 客户端
import javax.crypto.spec.*;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
import java.util.Scanner;

public class 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("127.0.0.1", 2010);
            in = new DataInputStream(mysocket.getInputStream());
            out = new DataOutputStream(mysocket.getOutputStream());
            KeyGenerator kg = KeyGenerator.getInstance("DESede");
            kg.init(168);
            SecretKey k = kg.generateKey();
            byte[] kb = k.getEncoded();
            System.out.println("请输入中缀表达式:");
            String infix = inn.nextLine();
            MyBC myBC = new MyBC();
            String suffix = myBC.infixToSuffix(infix);
            System.out.println(suffix);
            //中缀表达式加密
            Cipher cp = Cipher.getInstance("DESede");
            cp.init(Cipher.ENCRYPT_MODE, k);
            byte ptext[] = suffix.getBytes("UTF8");
            byte ctext[] = cp.doFinal(ptext);
            out.writeUTF(ctext.length + "");
            for (int i = 0; i < ctext.length; i++) {
                out.writeUTF(ctext[i] + "");
            }
            //对密钥进行加密
            KeyAgree keyAgree = new KeyAgree();
            SecretKeySpec k1 = keyAgree.KeyAgree("Serverpub.dat","Clientpri.dat");
            cp.init(Cipher.ENCRYPT_MODE, k1);
            byte ckey[] = cp.doFinal(kb);
            out.writeUTF(ckey.length + "");
            for (int i = 0; i < ckey.length; i++) {
                out.writeUTF(ckey[i] + "");
            }
            String result = in.readUTF();
            System.out.println("服务器收到请回去" + result);
            Thread.sleep(500);
        } catch (Exception e) {
            System.out.println("服务器断开连接" + e);
        }
    }
}
  • 服务器
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.net.*;
public class Server4 {
    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 e1){
            System.out.println("请提出问题"+e1);
        }
        try{
            System.out.println("等待中");
            socketOnServer = serverForClient.accept();
            out = new DataOutputStream(socketOnServer.getOutputStream());
            in = new DataInputStream(socketOnServer.getInputStream());
            //获取密文
            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);
            }
            //获取密钥
            String keylength = in.readUTF();
            byte []ckey = new byte[Integer.parseInt(keylength)];
            for(int i=0; i<Integer.parseInt(keylength); i++){
                String temp = in.readUTF();
                ckey[i] = Byte.parseByte(temp);
            }
            //密钥解密
            SecretKeySpec k1 = KeyAgree.KeyAgree("Clientpub.dat","Serverpri.dat");
            Cipher cp=Cipher.getInstance("DESede");
            cp.init(Cipher.DECRYPT_MODE, k1);
            byte []pkey=cp.doFinal(ckey);
            //密文解密
            SecretKeySpec k=new  SecretKeySpec(pkey,"DESede");
            cp.init(Cipher.DECRYPT_MODE, k);
            byte []ptext=cp.doFinal(ctext);
            String suffix = new String(ptext,"UTF8");
            System.out.println("受到提问"+suffix);
            out.writeUTF(myDC.evaluate(suffix)+"");
            Thread.sleep(500);
        }catch (Exception e){
            System.out.println("已断开连接");
        }
    }
}

实验截图

  • 任务五
  • 完整性校验结对编程:1人负责客户端,一人负责服务器
  • 注意责任归宿,要会通过测试证明自己没有问题
  • 基于Java Socket实现客户端/服务器功能,传输方式用TCP
  • 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加密通过网络把密文和明文的MD5値发送给服务器
  • 客户端和服务器用DH算法进行3DES或AES算法的密钥交换
  • 服务器接收到后缀表达式表达式后,进行解密,解密后计算明文的MD5值,和客户端传来的MD5进行比较,一致则调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
  • 客户端显示服务器发送过来的结果
  • 实验过程
  • Java摘要算法-MD5
  • 生成MessageDigest对象,MessageDigest m=MessageDigest.getInstance("MD5")
  • 传入需要计算的字符串,m.update(x.getBytes("UTF8" ))
  • 计算消息摘要,byte s[ ]=m.digest( )
  • 处理计算结果
    实验截图

おすすめ

転載: www.cnblogs.com/xyejava/p/10926705.html