java第四次实验_20135208 JAVA第四次实验

本文介绍了一个Java网络编程实验,包括客户端与服务器之间的数据传输、DES加密解密、RSA密钥加密解密等关键技术的实现过程。

课程:Java程序与设计     班级:1352姓名:贺邦小组成员: 20135212池彬宁 20135208贺邦

学号:20135208

成绩:             指导教师:娄嘉鹏       实验日期:2015.6.9

实验密级:预习程度:         实验时间:15:30-18:00

仪器组次:          必修/选修:选修        实验序号:5

实验名称:Java网络编程及安全

实验目的与要求:结对编程,实现客户端和服务器之间数据的发送与接收,实现加解密和验证Hash函数值。

实验仪器:

名称型号数量

PCLenovo Y510P1

Eclipse1

一、实验内容

1.用TCP代码,实现服务器与客户端。

2.客户端与服务器连接

3.客户端中输入明文,利用DES算法加密,DES的秘钥用RSA公钥密码中服务器的公钥加密.

4.客户端用RSA公钥密码中服务器的私钥解密DES的,秘钥,用秘钥对密文进行解密,得出明文。

二.实验过程。

注:我负责服务器。池彬宁负责客户端。本实验报告由我们共同完成。池彬宁的博客传送门:http://www.cnblogs.com/Spr1ngxx/。

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 此时客户端并没有此文件。

c16cc56677074cb29b1b4b23e359cff8.png

lib.txt表示明文

f9bc04fbb47ea113f8f0089cb3988139.png

通过服务器与客户端相连,服务器将加密后的文件jiami.txt传输给客户端待用。

b839f7be7543069f1f585884f226762a.png

acb33810b1a26ba4e83bdf7df52d091c.png

池彬宁收到加密后的密文 jiami.txt

5fa5ca9d79dddce4ea483d2d97f7e555.png

3.RSA加密密钥,传输,RSA解密获得密钥。

服务器使用已给出的代码加密密钥。因由老师提供,所以在这里不展示。

c1119f9eaa9f2ba7c5116df553e86186.png

e= 65537

n= 92762306318043317486801459248912293595003256010529294939223656563380834726026878628359253804733318625335965619370505821898698779510609617503818882582267688569453550369083515646002987933814065898437979454436295329681646858008489964667087321372289150075843191590922303967068927923924648679033628460820391822643

c= 45610250263003495738995686036440723189476581380781402714003262412563311443517019057690256196006821248391139776164481631183016800964563786560982066917233093226108879124297192365883788479891179243046071902705274073549706517017774091051461389961397719116709668717464178427493789177359622040310920723742910653005

将所加密内容发给客户端。并进行解密。

ba98f3ea1de967a02ac2e6de706fcc39.png

客户端解密后的密钥。

6996d9ca4bd98968e925fa4ac28cf9d2.png

4.应用密钥解密密文。

解密代码所生成的jiemi.txt。

eea69b813188bfdb02a870ddc849c8d9.png

99d001210d2950729662dc2eb306c0c1.png

【实验体会】

1.实验过程的理解,实验指导书中知识点的理解。

这次实验主要是练习在已有的代码之上如何把功能在同一个程序中实现,这给我们的编程带来了极大的方便,所以我们要做的就是熟悉这些代码所代表的含义,内化成自己的东西并能够掌握运用。课上

2. 实验过程中遇到的问题以及解决方案。

首先是没有搞清楚老师布置本次实验的目的,以及实验做法,在这方面浪费了大量时间,其实本次实验还是蛮简单的。

步骤耗时百分比

需求分析50m50%

设计10m10%

代码实现10m10%

测试20m20%

分析总结10m10%

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值