博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
20172319 实验五 《网络编程与安全》实验报告
阅读量:4600 次
发布时间:2019-06-09

本文共 11233 字,大约阅读时间需要 37 分钟。

20172319 2018.06.13-20

实验五《网络编程与安全》 实验报告
课程名称:《程序设计与数据结构》  学生班级:1723班  学生姓名:唐才铭  学生学号:20172319 实验教师:王志强老师课程助教:刘伟康、张旭升学长实验时间:2018年6月13日——2018年6月20日必修/选修:必修

目录

实验内容
  1. 参考
    结对实现中缀表达式转后缀表达式的功能 MyBC.java
    结对实现从上面功能中获取的表达式中实现后缀表达式求值的功能,调用MyDC.java
    上传测试代码运行结果截图和码云链接;
  2. 结对编程:1人负责客户端,一人负责服务器
    注意责任归宿,要会通过测试证明自己没有问题
    基于Java Socket实现客户端/服务器功能,传输方式用TCP
    客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式通过网络发送给服务器
    服务器接收到后缀表达式,调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
    客户端显示服务器发送过来的结果
    上传测试代码运行结果截图和码云链接;
  3. 加密结对编程:1人负责客户端,一人负责服务器
    注意责任归宿,要会通过测试证明自己没有问题
    基于Java Socket实现客户端/服务器功能,传输方式用TCP
    客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加密后通过网络把密文发送给服务器
    服务器接收到后缀表达式表达式后,进行解密(和客户端协商密钥,可以用数组保存),然后调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
    客户端显示服务器发送过来的结果
    上传测试结果截图和码云链接;
  4. 密钥分发结对编程:1人负责客户端,一人负责服务器
    注意责任归宿,要会通过测试证明自己没有问题
    基于Java Socket实现客户端/服务器功能,传输方式用TCP
    客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加密通过网络把密文发送给服务器
    客户端和服务器用DH算法进行3DES或AES算法的密钥交换
    服务器接收到后缀表达式表达式后,进行解密,然后调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
    客户端显示服务器发送过来的结果
    上传测试结果截图和码云链接;
  5. 完整性校验结对编程:1人负责客户端,一人负责服务器
    注意责任归宿,要会通过测试证明自己没有问题
    基于Java Socket实现客户端/服务器功能,传输方式用TCP
    客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加密通过网络把密文和明文的MD5値发送给服务器
    客户端和服务器用DH算法进行3DES或AES算法的密钥交换
    服务器接收到后缀表达式表达式后,进行解密,解密后计算明文的MD5值,和客户端传来的MD5进行比较,一致则调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
    客户端显示服务器发送过来的结果
    上传测试结果截图和码云链接:


实验要求
  1. 完成蓝墨云上与实验五《网络编程与安全》相关的活动,及时提交代码运行截图和码云Git链接,截图要有学号水印,否则会扣分。
  2. 完成实验、撰写实验报告,实验报告以博客方式发表在博客园,注意实验报告重点是运行结果,遇到的问题(工具查找,安装,使用,程序的编辑,调试,运行等)、解决办法(空洞的方法如“查网络”、“问同学”、“看书”等一律得0分)以及分析(从中可以得到什么启示,有什么收获,教训等)。报告可以参考范飞龙老师的。
  3. 严禁抄袭,有该行为者实验成绩归零,并附加其他惩罚措施。
  4. 结对编程;也可自己在idea和虚拟机间进行传输;idea本身也可以进行服务器与客户端的传输。


实验步骤
  1. 完成蓝墨云上实验五 网络编程与安全-1
  2. 完成蓝墨云上实验五 网络编程与安全-2
  3. 完成蓝墨云上实验五 网络编程与安全-3
  4. 完成蓝墨云上实验五 网络编程与安全-4
  5. 完成蓝墨云上实验五 网络编程与安全-5

前期准备:

  1. 弄清自己的IP地址是什么:
    Linux下查找IP的命令:ifconfig -a
    1334495-20180619223806412-2129552592.png
    Windows下查找IP的命令:ipconfig
    1334495-20180619224054263-831097581.png
    Windows下查找IP(笨方法):开始——设置——网络和Internet——WLAN——硬件属性
    1334495-20180619224523558-1217817303.png

需求分析:

  1. 需要在原Socket代码上加以理解并运用;
  2. 需要掌握、并会运用实验三java密码学所学的知识。


代码实现及解释

本次实验一共分为五个提交点:

  • 任务1:
  • 结对实现中缀表达式转后缀表达式的功能 MyBC.java;
    结对实现从上面功能中获取的表达式中实现后缀表达式求值的功能,调用MyDC.java
  • 分别运用四则运算时的中缀转后缀、后缀求值的方法即可:
  • ;
  • 截图如下:

    1334495-20180619230405233-61359235.png
    1334495-20180619230416742-1354597269.png

  • 任务2:
  • 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式通过网络发送给服务器
    服务器接收到后缀表达式,调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端。
  • 弄懂Socket的两个代码,将传输信息的内容换掉即可。
  • ;
  • 对客户端代码的修改:

String info1 = "12 15 8 100 25 34 19";

   变为

//客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式通过网络发送给服务器        Scanner scanner = new Scanner(System.in);        System.out.println("请输入中缀表达式");        String info1 = scanner.nextLine();        info1 = MyBC.infixToSuffix(info1);
  • 对服务器代码的修改:
String info=null;        if (!((info = bufferedReader.readLine()) ==null)){            System.out.println("我是服务器,用户信息为:" + info);        }        //给客户一个响应        //String reply=Output;        String reply = "welcome";        printWriter.write(reply);

   变为

String info=null;        if (!((info = bufferedReader.readLine()) ==null)){            System.out.println("我是服务器,用户信息为:" + info);        }        //服务器接收到后缀表达式,调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端        String reply = MyDC.suffixToArithmetic(info);        printWriter.write(reply);
  • 运行结果如下:

    1334495-20180619231725841-413500784.png
    1334495-20180619231818337-882653412.png

  • 任务3:

  • 让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加密后通过网络把密文发送给服务器
    服务器接收到后缀表达式表达式后,进行解密(和客户端协商密钥,可以用数组保存),然后调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端。
  • 运用java密码学里的3DES算法;先对文件(加密)和(解密)进行修改,使其从void变为String方法,返回密、明文;在客户端与服务器分别对需要传输的信息运用加解密方法。
  • 客户端:
//客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式        Scanner scanner = new Scanner(System.in);        System.out.println("请输入中缀表达式");        String info1 = scanner.nextLine();        info1 = MyBC.infixToSuffix(info1);        //把后缀表达式用3DES或AES算法加密后通过网络把密文发送给服务器        try {            info1 = SEnc.encrypt(info1);        } catch (Exception e) {            e.printStackTrace();        }        String info = new String(info1.getBytes("GBK"),"utf-8");        //     printWriter.write(info);        //     printWriter.flush();        outputStreamWriter.write(info);        outputStreamWriter.flush();        socket.shutdownOutput();
  • 服务器:
//4.读取用户输入信息        String info=null;        if (!((info = bufferedReader.readLine()) ==null)){            System.out.println("我是服务器,用户信息为:" + info);        }        //接收到后缀表达式表达式后,进行解密        try {            info = SDec.decode(info);        } catch (Exception e) {            e.printStackTrace();        }        //调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端        String reply = MyDC.suffixToArithmetic(info);        printWriter.write(reply);        printWriter.flush();
  • 运行结果:

    1334495-20180619232929959-1697996547.png
    1334495-20180619232954278-340305858.png

  • 任务4:
  • 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加密通过网络把密文发送给服务器
    客户端和服务器用DH算法进行3DES或AES算法的密钥交换
    服务器接收到后缀表达式表达式后,进行解密,然后调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端。
  • 修改java密码学中的Key_DH.java的代码,运行后分别生成客户端与服务器的公私钥;
  • ;
  • 运行结果如图:
    1334495-20180619233806640-1222671439.png
  • 对客户端的代码修改:
//客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式        Scanner scanner = new Scanner(System.in);        System.out.println("请输入中缀表达式");        String info1 = scanner.nextLine();        info1 = MyBC.infixToSuffix(info1);        //把后缀表达式用3DES或AES算法加密后通过网络把密文发送给服务器        try {            info1 = SEnc.encrypt(info1);        } catch (Exception e) {            e.printStackTrace();        }        // 客户端和服务器用DH算法进行3DES或AES算法的密钥交换        try{            // 读取对方的DH公钥            FileInputStream f1=new FileInputStream("Bpub.dat");            ObjectInputStream b1=new ObjectInputStream(f1);            PublicKey  pbk=(PublicKey)b1.readObject( );            //读取自己的DH私钥            FileInputStream f2=new FileInputStream("Apri.dat");            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("\n" + "公钥为:");            //生成共享信息            byte[ ] sb=ka.generateSecret();            for(int i=0;i
  • 对服务器的代码修改:
String info=null;        if (!((info = bufferedReader.readLine()) ==null)){            System.out.println("我是服务器,用户信息为:" + info);        }        //接收到后缀表达式表达式后,进行解密        try {            info = SDec.decode(info);        } catch (Exception e) {            e.printStackTrace();        }        // 客户端和服务器用DH算法进行3DES或AES算法的密钥交换        try{            // 读取对方的DH公钥            FileInputStream f1=new FileInputStream("Apub.dat");            ObjectInputStream b1=new ObjectInputStream(f1);            PublicKey pbk=(PublicKey)b1.readObject( );            //读取自己的DH私钥            FileInputStream f2=new FileInputStream("Bpri.dat");            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("\n" + "公钥为:");            //生成共享信息            byte[ ] sb=ka.generateSecret();            for(int i=0;i
  • 运行结果截图:

    1334495-20180619234004523-935353254.png
    1334495-20180619234010856-580227318.png

  • 任务5:
  • 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加密通过网络把密文和明文的MD5値发送给服务器
    客户端和服务器用DH算法进行3DES或AES算法的密钥交换
    服务器接收到后缀表达式表达式后,进行解密,解密后计算明文的MD5值,和客户端传来的MD5进行比较,一致则调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
  • 对客户端代码进行的修改:
//客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式        String a1,a2,a3,a4;        Scanner scanner = new Scanner(System.in);        System.out.println("请输入中缀表达式");        String info1 = scanner.nextLine();        info1 = MyBC.infixToSuffix(info1);  // 转后缀        a1 = info1 + "###";        String suffix = new String(a1.getBytes("GBK"),"utf-8");        outputStreamWriter.write(suffix);        outputStreamWriter.flush();        String cleartext = "",ciphertext = "";        //把后缀表达式用3DES或AES算法加密后通过网络把密文和明文的MD5値发送给服务器        try {             cleartext = DigestPass.MD5(info1); // 明文MID5            a2 = cleartext + "###";            String info_cleartext = new String(a2.getBytes("GBK"),"utf-8");            outputStreamWriter.write(info_cleartext);            outputStreamWriter.flush();            info1 = SEnc.encrypt(info1);  // 加密            a3 = info1 + "###";            String encrypt = new String(a3.getBytes("GBK"),"utf-8");            outputStreamWriter.write(encrypt);            outputStreamWriter.flush();             ciphertext = DigestPass.MD5(info1); // 密文MID5        } catch (Exception e) {            e.printStackTrace();        }        // 客户端和服务器用DH算法进行3DES或AES算法的密钥交换        try{            // 读取对方的DH公钥            FileInputStream f1=new FileInputStream("Bpub.dat");            ObjectInputStream b1=new ObjectInputStream(f1);            PublicKey  pbk=(PublicKey)b1.readObject( );            //读取自己的DH私钥            FileInputStream f2=new FileInputStream("Apri.dat");            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("\n" + "公钥为:");            //生成共享信息            byte[ ] sb=ka.generateSecret();            for(int i=0;i
  • 对服务器代码进行的修改:
//4.读取用户输入信息        String info,info1,info2,info3,info4,info5 = null,reply = null;        info = bufferedReader.readLine();        System.out.println("我是服务器,用户信息为:" + info);        String[] history = info.split("###");        info1 = history[0];            System.out.println("我是服务器,用户明文为:" + info1);        info2 = history[1];        System.out.println("我是服务器,用户明文MID5值为:" + info2);        info3 = history[2];        System.out.println("我是服务器,用户密文为:" + info3);        info4 = history[3];        System.out.println("我是服务器,用户密文MID5值为:" + info4);        //接收到后缀表达式表达式后,进行解密并计算器MID5值        try {            info3 = SDec.decode(info3);            info5 = DigestPass.MD5(info3);            System.out.println("解密后求得的MID5:" + info5);        } catch (Exception e) {            e.printStackTrace();        }        // 客户端和服务器用DH算法进行3DES或AES算法的密钥交换        try{            // 读取对方的DH公钥            FileInputStream f1=new FileInputStream("Apub.dat");            ObjectInputStream b1=new ObjectInputStream(f1);            PublicKey pbk=(PublicKey)b1.readObject( );            //读取自己的DH私钥            FileInputStream f2=new FileInputStream("Bpri.dat");            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("\n" + "公钥为:");            //生成共享信息            byte[ ] sb=ka.generateSecret();            for(int i=0;i
  • 运行结果截图:
    1334495-20180619234522272-286133208.png
    1334495-20180619234526957-1764419236.png


测试过程及遇到的问题
  • 问题1:'ipconfig' 不是内部或外部命令,也不是可运行的程序或批处理文件。
  • 解决:起初为了试验能进行,采用了需求分析里的笨方法,后来发现是环境变量的问题,参考即可解决。
  • 问题2:我作为客户端,伙伴作为服务器可以正常传输,而交换则显示connect timed out
  • 解决:当时电脑出现关于IDEA的警告,我允许了其行为,但并没有真正关掉防火墙,所以导致链接超时;

    开始——设置——更新和安全——windows安全——防火墙和保护——关掉公共网络的防火墙即可
    1334495-20180619235937741-611033136.png

  • 问题3:DH算法进行传输时两边的密钥不对等
  • 解决:刚开始我对Key_DH里的方法做了修改:

1334495-20180620001151288-115315338.png

  • 分别运用到服务器和客户端中,结果:
    1334495-20180620000918249-1790242437.png
    1334495-20180620000925136-1158806246.png
    很明显生成的公钥是不一样的,这明显不符合DH算法的原理;
    下面针对客户端与服务器的代码进行分析:
    1334495-20180620002617033-1450271653.png
    可以明显看出执行到try之后,已经使用了Key_DH.java中的client方法生成关于客户端的公私钥,这里显然没什么问题,
    但要小心,此时服务器的公钥Bpub.dat是读不到的,因为还没有任何操作进行相应的生成,之后当数据传输给服务器时,
    其实客户端只读取了客户端自己的私钥,而传给服务器的,仅仅是用私钥进行运算后的;
    再看服务器:
    1334495-20180620002130697-132192090.png
    一样的道理,在向客户端传回数据前并没有读到客户端的公钥Apub.dat,因此等同客户端,只进行了私钥的运算就传输了,
    所以二者才不一样。
  • 最后,将原文件Key_DH.java扩展成两个文件,直接运行生成二者的公私钥,在服务器与客户端不再进行生成操作,而是直接读取。
    1334495-20180619233806640-1222671439.png


分析总结
  • 本次实验,内容基本相关连,每一个都是在前者的基础上进行扩充,虽然看似简单,但其实也不太容易;回顾了java密码学的相关知识,学会了几种算法的基本应用,还学会如何在不同机器间进行传输。



参考资料

转载于:https://www.cnblogs.com/Tangcaiming/p/9200848.html

你可能感兴趣的文章
Linux-使用之vim编译安装出现的问题
查看>>
codevs 3314 魔法森林
查看>>
mac os x mysql 出现./mysql: unknown variable 'sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABL 问题...
查看>>
桐桐的贸易--WA
查看>>
历届试题 高僧斗法
查看>>
linux命令系列 stat & touch
查看>>
[Tools] Webstorm Github的配置与使用
查看>>
鬼谷子绝学
查看>>
Mongodb 笔记04 特殊索引和集合、聚合、应用程序设计
查看>>
使用Post/Redirect/Get实现Asp.net防止表单重复提交
查看>>
用Html5与Asp.net MVC上传多个文件
查看>>
lambda函数,常用函数,内置函数(string,zip()map()filter())的用法
查看>>
Xcode中匹配的配置包的存放目录
查看>>
JavaScript将具有父子关系的原始数据格式化成树形结构数据(id,pid)
查看>>
CSS3.0——背景属性
查看>>
【转载】C语言中的undefined behavior/unspecified behavior - 序
查看>>
MySQL服务使用
查看>>
C语言练手自己编写学生成绩管理系统
查看>>
20175204 张湲祯 2018-2019-2《Java程序设计》第二周学习总结
查看>>
NCPC 2015 - Problem A - Adjoin the Networks
查看>>