课程:Java程序与设计 班级:1352 姓 名:池彬宁 小组成员: 20135212池彬宁 20135208贺邦
学号:20135212
成绩: 指导教师:娄嘉鹏 实验日期:2015.6.9
实验密级: 预习程度: 实验时间:15:30-18:00
仪器组次: 必修/选修:选修 实验序号:5
实验名称:Java网络编程及安全
实验目的与要求:结对编程,实现客户端和服务器之间数据的发送与接收,实现加解密和验证Hash函数值。
实验仪器:
名称
|
型号
|
数量
|
PC
|
Sony TT1
|
1
|
Eclipse
|
|
1
|
一、实验内容
1.用TCP代码,实现服务器与客户端。
2.客户端与服务器连接
3.客户端中输入明文,利用DES算法加密,DES的秘钥用RSA公钥密码中服务器的公钥加密.
4.客户端用RSA公钥密码中服务器的私钥解密DES的,秘钥,用秘钥对密文进行解密,得出明文。
二.实验过程。
注:我负责客户端。贺邦负责服务器。本实验报告由我们共同完成。贺邦的博客传送门:http://www.cnblogs.com/L1nke/p/4430692.html
1.客户端 与服务器的连接。
服务器代码:
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
public class ServerTest {
int port = 8821;
void start() {
Socket s = null;
try {
ServerSocket ss = new ServerSocket(port); //创建一个ServerSocket套接字对象,并绑定在8821端口上
while (true) {
// 选择进行传输的文件
String filePath = "C:\\Users\\田雨晴\\Desktop\\服务器\\jiami.txt";
File fi = new File(filePath); //通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例
System.out.println("文件长度:" + (int) fi.length());
s = ss.accept();
System.out.println("建立socket链接");
DataInputStream dis = new DataInputStream(new BufferedInputStream(s.getInputStream())); //DataInputStream:使用指定的底层 InputStream 创建一个 DataInputStream;
dis.readByte(); //返回此输入流的下一个字节,以有符号 8 位 byte 的形式表示。
DataInputStream fis = new DataInputStream(new BufferedInputStream(new FileInputStream(filePath)));
DataOutputStream ps = new DataOutputStream(s.getOutputStream());//创建一个新的数据输出流,将数据写入指定基础输出流
ps.writeUTF(fi.getName());
ps.flush();
ps.writeLong((long) fi.length());
ps.flush();
int bufferSize = 8192; //缓冲区,1k
byte[] buf = new byte[bufferSize];
while (true) {
int read = 0;
if (fis != null) {
read = fis.read(buf);
}
if (read == -1) {
break;
}
ps.write(buf, 0, read);
}
ps.flush();// 直到socket超时,导致数据不完整。
fis.close();
s.close();
System.out.println("文件传输完成");
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String arg[]) {
new ServerTest().start();
}
}
客户端Socket代码:
import java.net.*;
import java.io.*;
public class ClientSocket {
private String ip;
private int port;
private Socket socket = null;
DataOutputStream out = null;
DataInputStream getMessageStream = null;
public ClientSocket(String ip, int port) {
this.ip = ip;
this.port = port;
}
/** *//**
* 创建socket连接
*
* @throws Exception
* exception
*/
public void CreateConnection() throws Exception {
try {
socket = new Socket(ip, port);
} catch (Exception e) {
e.printStackTrace();
if (socket != null)
socket.close();
throw e;
} finally {
}
}
public void sendMessage(String sendMessage) throws Exception {
try {
out = new DataOutputStream(socket.getOutputStream());
if (sendMessage.equals("Windows")) {
out.writeByte(0x1);
out.flush();
return;
}
if (sendMessage.equals("Unix")) {
out.writeByte(0x2);
out.flush();
return;
}
if (sendMessage.equals("Linux")) {
out.writeByte(0x3);
out.flush();
} else {
out.writeUTF(sendMessage);
out.flush();
}
} catch (Exception e) {
e.printStackTrace();
if (out != null)
out.close();
throw e;
} finally {
}
}
public DataInputStream getMessageStream() throws Exception {
try {
getMessageStream = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
return getMessageStream;
} catch (Exception e) {
e.printStackTrace();
if (getMessageStream != null)
getMessageStream.close();
throw e;
} finally {
}
}
public void shutDownConnection() {
try {
if (out != null)
out.close();
if (getMessageStream != null)
getMessageStream.close();
if (socket != null)
socket.close();
} catch (Exception e) {
}
}
}
客户端Test代码:
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
public class ClientTest {
private ClientSocket cs = null;
private String ip = "192.168.253.1";// 设置成服务器IP
private int port = 8821;
private String sendMessage = "Windwos";
public ClientTest() {
try {
if (createConnection()) {
sendMessage();
getMessage();
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
private boolean createConnection() {
cs = new ClientSocket(ip, port);
try {
cs.CreateConnection();
System.out.print("连接服务器成功!" + "\n");
return true;
} catch (Exception e) {
System.out.print("连接服务器失败!" + "\n");
return false;
}
}
private void sendMessage() {
if (cs == null)
return;
try {
cs.sendMessage(sendMessage);
} catch (Exception e) {
System.out.print("发送消息失败!" + "\n");
}
}
private void getMessage() {
if (cs == null)
return;
DataInputStream inputStream = null;
try {
inputStream = cs.getMessageStream();
} catch (Exception e) {
System.out.print("接收消息缓存错误\n");
return;
}
try {
//本地保存路径,文件名会自动从服务器端继承而来。
String savePath = "E:\\客户端\\";
int bufferSize = 8192;
byte[] buf = new byte[bufferSize];
int passedlen = 0;
long len=0;
savePath += inputStream.readUTF();
DataOutputStream fileOut = new DataOutputStream(new BufferedOutputStream(new BufferedOutputStream(new FileOutputStream(savePath))));
len = inputStream.readLong();
System.out.println("文件的长度为:" + len + "\n");
System.out.println("开始接收文件!" + "\n");
while (true) {
int read = 0;
if (inputStream != null) {
read = inputStream.read(buf);
}
passedlen += read;
if (read == -1) {
break;
}
//下面进度条本为图形界面的prograssBar做的,这里如果是打文件,可能会重复打印出一些相同的百分比
System.out.println("文件接收了" + (passedlen * 100/ len) + "%\n");
fileOut.write(buf, 0, read);
}
System.out.println("接收完成,文件存为" + savePath + "\n");
fileOut.close();
} catch (Exception e) {
System.out.println("接收消息错误" + "\n");
return;
}
}
public static void main(String arg[]) {
new ClientTest();
}
}
在这只做简单代码展示,具体传输文件见下述步骤。
2.用DES加密明文,并传输给服务器密文。
DES加密代码:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
public class JiaMi {
public static void main(String[] args) throws Exception {
// DES算法要求有一个可信任的随机数源
SecureRandom sr = new SecureRandom();
// 获得密匙数据
FileInputStream fi = new FileInputStream(new File("key.txt"));
byte rawKeyData[] = new byte[fi.available()];
fi.read(rawKeyData);
fi.close();
// 从原始密匙数据创建DESKeySpec对象
DESKeySpec dks = new DESKeySpec(rawKeyData);
// 创建一个密匙工厂,然后用它把DESKeySpec转换成一个SecretKey对象
SecretKey key = SecretKeyFactory.getInstance("DES").generateSecret(dks);
// Cipher对象实际完成加密操作
Cipher cipher = Cipher.getInstance("DES");
// 用密匙初始化Cipher对象
cipher.init(Cipher.ENCRYPT_MODE, key, sr);
// 现在,获取要加密的文件数据
FileInputStream fi2 = new FileInputStream(new File("lib.txt"));
byte data[] = new byte[fi2.available()];
fi2.read(data);
fi2.close();
// 正式执行加密操作
byte encryptedData[] = cipher.doFinal(data);
// 用加密后的数据文件
FileOutputStream fo = new FileOutputStream(new File("jiami.txt"));
fo.write(encryptedData);
fo.close();
new ServerTest().start();
}
}
DES解密代码:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
public class JieMi {
public static void main(String[] args) throws Exception {
new ClientTest();
// DES算法要求有一个可信任的随机数源
SecureRandom sr = new SecureRandom();
// 获得密匙数据
FileInputStream fi = new FileInputStream(new File("key.txt"));
byte rawKeyData[] = new byte[fi.available()];// = new byte[5];
fi.read(rawKeyData);
fi.close();
// 从原始密匙数据创建一个DESKeySpec对象
DESKeySpec dks = new DESKeySpec(rawKeyData);
// 创建一个密匙工厂,然后用它把DESKeySpec对象转换成一个 SecretKey对象
SecretKey key = SecretKeyFactory.getInstance("DES").generateSecret(dks);
// Cipher对象实际完成解密操作
Cipher cipher = Cipher.getInstance("DES");
// 用密匙初始化Cipher对象
cipher.init(Cipher.DECRYPT_MODE, key, sr);
// 现在,获取数据并解密
FileInputStream fi2 = new FileInputStream(new File("jiami.txt"));
byte encryptedData[] = new byte[fi2.available()];
fi2.read(encryptedData);
fi2.close();
// 正式执行解密操作
byte decryptedData[] = cipher.doFinal(encryptedData);
// 这时把数据还原成原有的类文件
FileOutputStream fo = new FileOutputStream(new File("jiemi.txt"));
fo.write(decryptedData);
}
}
我们所采用的密钥 key.txt 此时客户端并没有此文件。
lib.txt表示明文
通过服务器与客户端相连,服务器将加密后的文件jiami.txt传输给客户端待用。
池彬宁收到加密后的密文 jiami.txt
3.RSA加密密钥,传输,RSA解密获得密钥。
服务器使用已给出的代码加密密钥。因由老师提供,所以在这里不展示。
e= 65537
n= 92762306318043317486801459248912293595003256010529294939223656563380834726026878628359253804733318625335965619370505821898698779510609617503818882582267688569453550369083515646002987933814065898437979454436295329681646858008489964667087321372289150075843191590922303967068927923924648679033628460820391822643
c= 45610250263003495738995686036440723189476581380781402714003262412563311443517019057690256196006821248391139776164481631183016800964563786560982066917233093226108879124297192365883788479891179243046071902705274073549706517017774091051461389961397719116709668717464178427493789177359622040310920723742910653005
将所加密内容发给客户端。并进行解密。
客户端解密后的密钥。
4.应用密钥解密密文。
解密代码所生成的jiemi.txt。
【实验体会】
1.实验过程的理解,实验指导书中知识点的理解。
这次实验主要是练习在已有的代码之上如何把功能在同一个程序中实现,这给我们的编程带来了极大的方便,所以我们要做的就是熟悉这些代码所代表的含义,内化成自己的东西并能够掌握运用。课上
2. 实验过程中遇到的问题以及解决方案。
首先是没有搞清楚老师布置本次实验的目的,以及实验做法,在这方面浪费了大量时间,其实本次实验还是蛮简单的。
步骤
|
耗时
|
百分比
|
需求分析
|
50m
|
50%
|
设计
|
10m
|
10%
|
代码实现
|
10m
|
10%
|
测试
|
20m
|
20%
|
分析总结
|
10m
|
10%
|
- 南京邮电大学java第四次实验报告
实 验 报 告 ( 2017 / 2018学年 第2学期) 课程名称 JAVA语言程序设计 实验名称 Java集成开发环境的安装与使用. Java变量.表达式与控制结构 实验时间 2018 年 6 月 ...
- 20165210 Java第四次实验报告
20165210 实验四 Android程序设计 实验步骤 第24章:初识Android 任务一:完成Hello World, 要求修改res目录中的内容,Hello World后要显示自己的学号 学 ...
- 20145330《Java程序设计》第四次实验报告
20145330<Java程序设计>第四次实验报告 实验四 Android环境搭建 实验内容 1.搭建Android环境 2.运行Android 3.修改代码,能输出学号 实验步骤 搭建A ...
- 20145320《Java程序设计》第四次实验报告
20145320<Java程序设计>第四次实验报告 北京电子科技学院(BESTI)实验报告 课程:Java程序设计 班级:1453 指导教师:娄嘉鹏 实验日期:2016.04.26 15: ...
- 2017-2018-2 20165301 实验四《Java面向对象程序设计》实验报告
2017-2018-2 20165301 实验四<Java面向对象程序设计>实验报告 一.Android Stuidio的安装测试 实验要求: 参考<Java和Android开发学习 ...
- 20155201 实验四《Java面向对象程序设计》实验报告
20155201 实验四<Java面向对象程序设计>实验报告 一.实验内容 1.基于Android Studio开发简单的Android应用并部署测试; 2.了解Android.组件.布局 ...
- 20155217 实验四《Java面向对象程序设计》实验报告
20155217 实验四<Java面向对象程序设计>实验报告 一.实验内容 1.基于Android Studio开发简单的Android应用并部署测试; 2.了解Android.组件.布局 ...
- 20145240 《Java程序设计》第四次实验报告
20145240 <Java程序设计>第四次实验报告 北京电子科技学院(BESTI)实验报告 课程:Java程序设计 班级:1452 指导教师:娄嘉鹏 实验日期:2016.04.26 实验 ...
- 20145238-荆玉茗 《Java程序设计》第四次实验报告
20145238<Java程序设计>第四次实验报告 实验四 Android环境搭建 实验内容 1.搭建Android环境 2.运行Android 3.修改代码,能输出学号 实验步骤 搭建A ...
随机推荐
- Linux Shell常用技巧(一)
一. 特殊文件: /dev/null和/dev/tty Linux系统提供了两个对Shell编程非常有用的特殊文件,/dev/null和/dev/tty.其中/dev/null将会丢掉所有写入它 ...
- Oracle 下马观花看redo
----------------------------------------- --Lerning Content :Oracle 下马观花看redo --Author :如人饮水冷暖自知 --版 ...
- 从0开始学golang--2.2--如何去爬园子的数据👉进阶篇,面向对象的单任务版
执行页main.go-----------------------------------代码
- 【Verilog HDL】赋值语句之阻塞赋值方式与非阻塞赋值方式
刚开始接触Verilog HDL语言时,这种硬件描述语言有一点与软件的程序设计语言直观上的最大区别大概就是这个赋值语句了(这里只是强调直观上的最大区别,事实上的最大区别并非如此). Verilog H ...
- WPF触控方面的技术点
一.基本的触控事件(原始触控) 二.复杂触控事件(操作)
- ASP.NET中关于XML的AJAX的读取与删除
一个XML文件,名称就暂定为GroupStudents.xml吧,内容如下: <?xml version="1.0" encoding="utf-8"?& ...
- 20155236范晨歌 Exp1PC平台逆向破解及Bof基础实践
出现的问题及解决: 在下载execstack时,出现了下列签名无效的错误! 解决方案:发现是密钥过期了,将新的密钥填入apt-keyring 输入命令:apt-key adv --keyserver ...
- RabbitMQ(一):Window安装RabbitMQ
原文:RabbitMQ(一):Window安装RabbitMQ 1.安装ERLANG语言环境 由于RabbitMQ是采用Erlang编写的,因此我们需要先安装该语言库,以便运行代理服务器.从Erlan ...
- 为firefox添加flash插件
需要自行下载flash for firefox进行安装,安装后即可看到 Shockwave Flash 插件
- 指定路由器(DR/BDR)和非指定路由器(DROTHER)的区别
一:名词解释 DR:designated router 指定路由器. BDR:backup designated router 备份指定路由器. 二:DR/BDR出现的缘由 在广播网和NBMA网络中, ...