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

课程:《程序设计与数据结构》

班级: 1723

姓名: 方艺雯

学号:20172314

实验教师:王志强

实验日期:2018年6月13日

必修/选修: 必修

1、实验内容及要求

  • 实验五-1

    两人一组结对编程:
    0. 参考http://www.cnblogs.com/rocedu/p/6766748.html#SECDSA

    1. 结对实现中缀表达式转后缀表达式的功能 MyBC.java
    2. 结对实现从上面功能中获取的表达式中实现后缀表达式求值的功能,调用MyDC.java
    3. 上传测试代码运行结果截图和码云链接
  • 实验五-2

    结对编程:1人负责客户端,一人负责服务器
    0. 注意责任归宿,要会通过测试证明自己没有问题

    1. 基于Java Socket实现客户端/服务器功能,传输方式用TCP
    2. 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式通过网络发送给服务器
    3. 服务器接收到后缀表达式,调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
    4. 客户端显示服务器发送过来的结果
    5. 上传测试结果截图和码云链接
  • 实验五-3

    加密结对编程:1人负责客户端,一人负责服务器
    0. 注意责任归宿,要会通过测试证明自己没有问题

    1. 基于Java Socket实现客户端/服务器功能,传输方式用TCP
    2. 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加密后通过网络把密文发送给服务器
    3. 服务器接收到后缀表达式表达式后,进行解密(和客户端协商密钥,可以用数组保存),然后调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
    4. 客户端显示服务器发送过来的结果
    5. 上传测试结果截图和码云链接
  • 实验五-4

    密钥分发结对编程:1人负责客户端,一人负责服务器
    0. 注意责任归宿,要会通过测试证明自己没有问题

    1. 基于Java Socket实现客户端/服务器功能,传输方式用TCP
    2. 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加密通过网络把密文发送给服务器
    3. 客户端和服务器用DH算法进行3DES或AES算法的密钥交换
    4. 服务器接收到后缀表达式表达式后,进行解密,然后调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
    5. 客户端显示服务器发送过来的结果
    6. 上传测试结果截图和码云链接
  • 实验五-5

    实验五 网络编程与安全-5
    完整性校验结对编程:1人负责客户端,一人负责服务器
    0. 注意责任归宿,要会通过测试证明自己没有问题

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

实验过程及结果

实验5-1

  • 过程

    利用博客中的MyDC、MyBC的代码,并编写计算类,MyBC是将中缀式转为后缀式,MyDC是计算后缀式的值。计算类代码:

    package test;
    
    import java.util.*;
    
    public class Calculator {
        public static void main(String[] args) {
        String string;
        int result;
    
        MyBC a = new MyBC();
        MyDC b = new MyDC();
    
    
        System.out.println("请输入中缀式:");
        Scanner xxx = new Scanner(System.in);
        string = xxx.nextLine();
    
        a.conversion(string);
        System.out.println("后缀表达式是:"+ a.getMessage());
    
        result = b.evaluate(a.getMessage());
        System.out.println("式子的结果是:"+ result);
    }
    }
    
  • 实验结果

实验5-2

  • 过程
    我负责的是客户端,在实验5-1的基础上,将客户端与服务端连接后,关键代码是:
    Scanner xxx = new Scanner(System.in);
        String a;
    
        System.out.println("请输入中缀表达式:");
        a = xxx.nextLine();
    
        MyBC b = new MyBC();
        b.conversion(a);
    
        String info1 =b.getMessage();
        String info = new String(info1.getBytes("utf-8"));
        //     printWriter.write(info);
        //     printWriter.flush();
        outputStreamWriter.write(info);
        outputStreamWriter.flush();
        socket.shutdownOutput();
    
    服务端的关键代码是:
      MyDC b = new MyDC();
       String info=null;
       String result = "";
       int xxx;
    
       info = bufferedReader.readLine();
       xxx = b.evaluate(info);
    
       result = Integer.toString(xxx);
        System.out.println(result);
    
  • 实验结果

实验5-3

  • 过程

    • 实现DES加密的主要步骤:
      • 对称密钥的生成和保存
      • 使用对称密钥进行加密和解密
      • 从文件中获取加密时使用的密钥,使用密钥进行解密
  • 实验结果

实验5-4

  • 过程
    • 执行密钥协定的标准算法是DH算法(Diffie-Hellman算法),Diffie-Hellman是一种建立密钥的方法,而不是加密方法。然而,它所产生的密钥可用于加密、进一步的密钥管理或任何其它的加密方式。
    • 分为以下两步:
      • 创建DH公钥和私钥,保存在两个文件中
      • 将两个密钥合并,创建共享密钥
  • 实验结果

实验5-5

  • 过程

    • 可以使用Java计算指定字符串的消息摘要。java.security包中的MessageDigest类提供了计算消息摘要的方法,首先生成对象,执行其update()方法可以将原始数据传递给该对象,然后执行其digest( )方法即可得到消息摘要。
    • 加密:
    public class DigestPass{
        public static String DP(String s1) throws Exception{
            String x=s1;
            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);//将加密结果转换为16进制字符串
        }
        return result;//返回加密后的结果
    }
    }
    
  • 实验结果

遇到的问题及解决

  • 问题一:在做实验5-3时,尝试得出密钥然后发给小伙伴,以“,”作为分割线结果报错

  • 问题一解决:错误的原因在于“,”与数字之间还有空格,解决方法为把字符串中的空格删去,或者把标记改为“, ”

  • 问题二:产生异常“connection reset”

  • 问题二解决:网上查找解决办法,有如下问题参考:什么情况下会产生Connection reset

    第1个异常是java.net.BindException:Address already in use: JVM_Bind。该异常发生在服务器端进行new ServerSocket(port)(port是一个0,65536的整型值)操作时。异常的原因是以为与port一样的一个端口已经被启动,并进行监听。此时用netstat –an命令,可以看到一个Listending状态的端口。只需要找一个没有被占用的端口就能解决这个问题。

    第2个异常是java.net.ConnectException: Connection refused: connect。该异常发生在客户端进行new Socket(ip, port)操作时,该异常发生的原因是或者具有ip地址的机器不能找到(也就是说从当前机器不存在到指定ip路由),或者是该ip存在,但找不到指定的端口进行监听。出现该问题,首先检查客户端的ip和port是否写错了,如果正确则从客户端ping一下服务器看是否能ping通,如果能ping通(服务服务器端把ping禁掉则需要另外的办法),则看在服务器端的监听指定端口的程序是否启动,这个肯定能解决这个问题。

    第3个异常是java.net.SocketException: Socket is closed,该异常在客户端和服务器均可能发生。异常的原因是己方主动关闭了连接后(调用了Socket的close方法)再对网络连接进行读写操作。

    第4个异常是java.net.SocketException: (Connection reset或者Connect reset by peer:Socket write error)。该异常在客户端和服务器端均有可能发生,引起该异常的原因有两个,第一个就是如果一端的Socket被关闭(或主动关闭或者因为异常退出而引起的关闭),另一端仍发送数据,发送的第一个数据包引发该异常(Connect reset by peer)。另一个是一端退出,但退出时并未关闭该连接,另一端如果在从连接中读数据则抛出该异常(Connection reset)。简单的说就是在连接断开后的读和写操作引起的。

    第5个异常是java.net.SocketException: Broken pipe。该异常在客户端和服务器均有可能发生。在第4个异常的第一种情况中(也就是抛出SocketExcepton:Connect reset by peer:Socket write error后),如果再继续写数据则抛出该异常。前两个异常的解决方法是首先确保程序退出前关闭所有的网络连接,其次是要检测对方的关闭连接操作,发现对方关闭连接后自己也要关闭该连接。

    发现是有第四个异常的可能,没有按照正确的连接步骤,所以一个可能关闭了,另一个就无法传输数据。在进行客户端与服务端的连接时,首先要注意正确填写地址与端口,其次是先运行服务端,后运行客户端。

  • 问题三:* 在做这个实验时,根据老师提示,想着把密钥发给服务端即可,但是用qq发送总会改变密钥并且添加表情。

  • 问题三解决:尝试了各种办法,最后将密钥单独运行出来,就可以将一个数字组成的字符串发给服务端。不过最终这个方法总是出错就放弃了。

其他

这次实验结合了密码算法,由于对密码不是很了解,所以实验还是有一点难度的,但学习之后对客户端和服务端的连接有了更深的理解,对密码的一些相关算法有了全面的认识。

参考

原文地址:https://www.cnblogs.com/YiYiYi/p/9196110.html