20145314郑凯杰 《Java程序设计》实验五 实验报告

20145314郑凯杰 《Java程序设计》实验五 实验报告

实验搭档王亦徐:http://www.cnblogs.com/1152wyx/p/5471524.html

实验要求

  1. 完成实验、撰写实验报告,实验报告以博客方式发表在博客园,注意实验报告重点是运行结果,遇到的问题(工具查找,安装,使用,程序的编辑,调试,运行等)、解决办法(空洞的方法如“查网络”、“问同学”、“看书”等一律得0分)以及分析(从中可以得到什么启示,有什么收获,教训等)。报告可以参考范飞龙老师的指导
  2. 严禁抄袭,有该行为者实验成绩归零,并附加其他惩罚措施。

实验内容

1.

掌握Socket程序的编写;

  1. 掌握密码技术的使用;
  2. 设计安全传输系统。

实验知识点

  1. 用书上的TCP代码,实现服务器与客户端。
  2. 客户端与服务器连接。
  3. 客户端中输入明文,利用DES算法加密,DES的秘钥用RSA公钥密码中服务器的公钥加密,计算明文的Hash函数值,一起传送给客户端。
  4. 客户端用RSA公钥密码中服务器的私钥解密DES的,秘钥,用秘钥对密文进行解密,得出明文。计算求得明文的Hash函数值,检查是否与传送过来的一致,如果一致,则表示匹配成功。

原理图如下

插图一:

信息(明文)采用DES密钥加密,使用RSA加密前面的DES密钥信息,最终将混合信息进行传递。同时用hash函数将明文进行用作验证。

而接收方(本次实验为服务器)接收到信息后,用RSA解密DES密钥信息,再用RSA解密获取到的密钥信息解密密文信息,最终就可以得到我们要的明文。用hash函数对解出的明文进行验证,与发送过来的hash值相等,验证通过。稍后我将用"hello bitch"与我的搭档王亦徐进行沟通,接下来请看实验步骤:

实验步骤

本次实验伙伴20145311王亦徐

1、首先与王亦徐连上同一个WIFI,我们采用手机热点,稳定且相同的网络是做好本次实验的基础。

2、接着在王亦徐的命令行中输入ipconfig得到服务器的ip地址。

王亦徐IP:

3、GET到王亦徐的IP地址之后,我们就可以建立一个Socket对象,用来连接特定服务器的指定端口,输入的参数是刚刚获取的ip地址和双方默认的同一端口。我们端口号是9090。

因此,我们的Socket实例为:Socket socket = new Socket("172.26.168.2", 9090);

4、接着利用BufferedReader对象获得从服务器传来的网络输入流,用PrintWriter对象获得从客户端向服务器输出数据的网络输出流,用BufferedReader对象创建键盘输入流,以便客户端从键盘上输入信息。这部分直接可以用到老师给我们的代码,我是客户端,所以代码如下:

package com.company;

import java.net.*;
import java.io.*;
import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import java.security.spec.*;
import javax.crypto.interfaces.*;
import java.security.interfaces.*;
import java.math.*;

public class Main
{
public static void main(String srgs[]) throws Exception
{
        try
        {
            KeyGenerator kg = KeyGenerator.getInstance("DESede");
            kg.init(168);
            SecretKey k = kg.generateKey();
            byte[] ptext2 = k.getEncoded();

            // 创建连接特定服务器的指定端口的Socket对象
            Socket socket = new Socket("172.26.168.2", 9090);//这里输入的是服务器的ip地址和端口号,端口号要注意和服务器保持一致。

            // 获得从服务器端来的网络输入流
        BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

        // 获得从客户端向服务器端输出数据的网络输出流
        PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);

        // 创建键盘输入流,以便客户端从键盘上输入信息
        BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));

        //RSA算法,使用服务器端的公钥对DES的密钥进行加密
        FileInputStream f3 = new FileInputStream("Skey_RSA_pub.dat");
        ObjectInputStream b2 = new ObjectInputStream(f3);
        RSAPublicKey pbk = (RSAPublicKey) b2.readObject();
        BigInteger e = pbk.getPublicExponent();
        BigInteger n = pbk.getModulus();
        BigInteger m = new BigInteger(ptext2);
        BigInteger c = m.modPow(e, n);
        String cs = c.toString();
        out.println(cs); // 通过网络将加密后的秘钥传送到服务器

        //用DES加密明文得到密文
        System.out.print("请输入待发送的数据:");
        String s = stdin.readLine(); // 从键盘读入待发送的数据
        Cipher cp = Cipher.getInstance("DESede");
        cp.init(Cipher.ENCRYPT_MODE, k);
        byte ptext[] = s.getBytes("UTF8");
        byte ctext[] = cp.doFinal(ptext);
        String str = parseByte2HexStr(ctext);
        out.println(str); // 通过网络将密文传送到服务器

        // 将客户端明文的Hash值传送给服务器
        String x = s;
        MessageDigest m2 = MessageDigest.getInstance("MD5");
        m2.update(x.getBytes());
        byte a[] = m2.digest();
        String result = "";
        for (int i = 0; i < a.length; i++)
        {
            result += Integer.toHexString((0x000000ff & a[i]) | 0xffffff00).substring(6);
        }
        System.out.println(result);
        out.println(result);//通过网络将明文的Hash函数值传送到服务器

        str = in.readLine();// 从网络输入流读取结果
        System.out.println("从服务器接收到的结果为:" + str); // 输出服务器返回的结果
    }
    catch (Exception e)
    {
        System.out.println(e);//输出异常
    }
    finally
    {

    }

}

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

5、得到了明文就可以将客户端明文的Hash值传送给服务器,然后会收到来自服务器的返回数据

6、实验就成功了:

成功 王亦徐:

成功 郑凯杰:

实验中的问题和解决过程

1、第一个遇到的问题是WIFI问题

如果双方连接CMCC-EDU的话,成功率是比较低的。

就会出现连接超时的问题:

失败:

这是由于有些端口已被占用,这时候我们可以用以下三种方法解决这个问题:

①可以用老师上传给我们的XAMPP软件,查看已被使用的端口十分方便。

②可以在命令行中输入netstat -na就能看到当前的端口号的占用情况。

③连接私人WIFI,即手机热点,成功率暴涨。

2、文件缺失问题

相信大家第一次做都会出现如下情况:

失败 缺失文件:

我们只要将老师给我们的文件拷入JDK目录下即可:

找不到文件解决:

实验代码托管截图

代码:

其他(感悟、思考等,可选)

最后一次JAVA实验,这次的实验实用性比较强,而且结合了本周学习内容——网络编程。实验与知识契合度高的话做起来也比较快。本次实验找到了搭档王亦徐,配合起来也比较快,一对一进行实验,对于处理和分析问题,效率大大提高。两个人也对同一个问题有着不同的解决方法,所以今天的解决方法比较多。相信下周开始做项目之后会取得更好的效果!

PSP

PSP:

posted on 2016-05-08 22:45  20145314郑凯杰  阅读(215)  评论(2编辑  收藏  举报

导航