20145314郑凯杰 《Java程序设计》实验五 实验报告
实验搭档王亦徐:http://www.cnblogs.com/1152wyx/p/5471524.html
实验要求
- 完成实验、撰写实验报告,实验报告以博客方式发表在博客园,注意实验报告重点是运行结果,遇到的问题(工具查找,安装,使用,程序的编辑,调试,运行等)、解决办法(空洞的方法如“查网络”、“问同学”、“看书”等一律得0分)以及分析(从中可以得到什么启示,有什么收获,教训等)。报告可以参考范飞龙老师的指导
- 严禁抄袭,有该行为者实验成绩归零,并附加其他惩罚措施。
实验内容
1.
掌握Socket程序的编写;
- 掌握密码技术的使用;
- 设计安全传输系统。
实验知识点
- 用书上的TCP代码,实现服务器与客户端。
- 客户端与服务器连接。
- 客户端中输入明文,利用DES算法加密,DES的秘钥用RSA公钥密码中服务器的公钥加密,计算明文的Hash函数值,一起传送给客户端。
- 客户端用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: