北京电子科技学院(BESTI)

实     验    报     告

课程:Java    班级:1352班      姓名:王国伊    学号:20135207

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

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

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

实验名称:  服务器与客户端间传送信息加解密

实验目的与要求: 1.没有Linux基础的同学建议先学习《Linux基础入门(新版)》《Vim编辑器》 课程。

2.使用实验楼git服务托管代码。

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

4. 严禁抄袭,有该行为者实验成绩归零,并附加其他惩罚措施。

实验仪器:

名称

型号

数量

笔记本电脑

Lenovo Z485

1台

实验内容、步骤与体会(附纸):

一、实验内容

1. 先运行教材上TCP代码,一人服务器,一人客户端。

2. 下载加解密代码,先编译运行代码,一人加密一人解密,适当修改代码。

3. 然后集成代码,一人加密后通过TCP发送,加密使用AES或DES,AES或DES加密密钥Key的发送,使用服务器的公钥加密,公钥算法用RSA或DH,发送信息的完整性验证使用MD5或SHA3。

4.使用试验后git服务托管代码。

5.完成实验后,找老师验收,课下写Blog。

二、实验步骤

结对同学:20135115 臧文君

Blog网址:http://www.cnblogs.com/CatherineZang/

1、实验分工:臧文君---服务器,加解密代码整合。

王国伊---客户端,实现两台PC机相连。

2、实验步骤:

(1)下载老师提供的加解密代码,分析理解代码中语句的功能。

(2)根据代码中的语句,查找自己主机的IP地址,确定端口号。

在命令行中输入:ipconfig。

找到自己主机的IP地址为:222.28.128.119。

(3)根据书上TCP的实例,用BufferedReader获取从服务器传入的数据流,再用PrintWriter获取从客户端传出的输出流。

(4)用RSA算法加密,加密使用服务器的公钥,再将加密后的密钥传给服务器。

(5)用DES算法加密输入的明文,将加密后的密文传给服务器。

(6)使用Hash函数,计算明文的Hash函数值,传给服务器。

(7)把从服务器返回的结果输出。

3、代码:

服务器:

package exp4;

import java.net.*;

import java.io.*;

import java.security.*;

import java.security.spec.*;

import javax.crypto.*;

import javax.crypto.spec.*;

import javax.crypto.interfaces.*;

import java.security.interfaces.*;

import java.math.*;

public class Server {

public static void main(String srgs[]) throws Exception {

ServerSocket sc = null;

Socket socket = null;

try {

sc = new ServerSocket(8029);// 创建服务器套接字

System.out.println("端口号:" + sc.getLocalPort());

System.out.println("服务器已经启动...");

socket = sc.accept(); // 等待客户端连接

System.out.println("已经建立连接");

// 获得网络输入流对象的引用

BufferedReader in = new BufferedReader(new InputStreamReader(

socket.getInputStream()));

// //获得网络输出流对象的引用

PrintWriter out = new PrintWriter(new BufferedWriter(

new OutputStreamWriter(socket.getOutputStream())), true);

String aline2 = in.readLine();

BigInteger c = new BigInteger(aline2);

FileInputStream f = new FileInputStream("Skey_RSA_priv.dat");

ObjectInputStream b = new ObjectInputStream(f);

RSAPrivateKey prk = (RSAPrivateKey) b.readObject();

BigInteger d = prk.getPrivateExponent();

BigInteger n = prk.getModulus();

BigInteger m = c.modPow(d, n);

byte[] keykb = m.toByteArray();

String aline = in.readLine();// 读取客户端传送来的数据

byte[] ctext = parseHexStr2Byte(aline);

Key k = new SecretKeySpec(keykb, "DESede");

Cipher cp = Cipher.getInstance("DESede");

cp.init(Cipher.DECRYPT_MODE, k);

byte[] ptext = cp.doFinal(ctext);

String p = new String(ptext, "UTF8");

System.out.println("从客户端接收到信息为:" + p); // 通过网络输出流返回结果给客户端

String aline3 = in.readLine();

String x = p;

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

if (aline3.equals(result)) {

System.out.println("匹配成功");

}

out.println("匹配成功");

out.close();

in.close();

sc.close();

} catch (Exception e) {

System.out.println(e);

}

}

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;

}

}

客户端:

package exp4;

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 Client {

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("222.28.128.119", 8028);

// 网络输入流

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

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); // 通过网络传送到服务器

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

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

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;

}

}

三、实验体会

本次实验是java课的最后一次实验,首先十分感谢娄老师对我们的殷切指导与教育。虽然过程中有一些觉得困难的时候。但最后的确学到一些很实用的技巧与编程思想。这使得对理解计算机语言思想有很大帮助。特别是对于面向对象的思想对于无论是理解现实生活的问题还是计算机需要处理的问题都是一种很有效的思想。

对于本次实验,相比于上次的XP实践来讲有提升一个层次,要求在网络中实现。而且传输数据要求加密,这与我们的专业有息息相关,无论是加解密代码还是客户端服务器的建立,都有很大的实际应用意义。在与伙伴的网络连接中,总会出现无效长度的情况。后来将RSA的全部dat文件放到程序调用路径中又更换了端口重新连接几次了才可以传输数据。最终完成了实验。

附:

步骤

耗时

百分比

需求分析

0.5h

5%

设计

1.5h

15%

代码实现

5h

50%

测试

2h

20%

分析总结

1h

10%

Java实验报告(实验四)的更多相关文章

  1. 第六周课程总结&实验报告(四)

    实验报告(四) 一.实验目的 1.掌握类的继承 2.变量的继承和覆盖,方法的继承,重载和覆盖的实现 二.实验的内容 1.根据下面的要求实现圆类Circle. 圆类Circle的成员变量:radius表 ...

  2. 第六周总结 & 实验报告(四)

    第六周小结 一.instanceof关键字         在Java中使用instanceof关键字判断一个对象到底是哪个类的实例,返回boolean类型 1.instanceof关键字的作用 例c ...

  3. JAVA课程实验报告 实验二 Java面向对象程序设计

    北京电子科技学院(BESTI) 实     验    报     告 课程:Java程序设计  班级:1353  姓名:韩玉琪  学号:20135317 成绩:             指导教师:娄嘉 ...

  4. Java课程实验报告 实验四 Java网络编程及安全

    北京电子科技学院(BESTI) 实     验    报     告 课程:Java程序设计     班级:1352     姓名:吕松鸿  学号:20135229 成绩:               ...

  5. Java实验报告(四)&第六周学习总结

    班级 计科二班 学号 20188425 姓名 IM 完成时间2019/10/07 评分等级 一.实验目的 (1)掌握类的继承 (2)变量的继承和覆盖,方法的继承,重载和覆盖的实现: 二.实验的内容 ( ...

  6. JAVA课程实验报告 实验三 敏捷开发与XP实践

    北京电子科技学院(BESTI) 实     验    报     告 课程:Java程序设计  班级:1353  姓名:韩玉琪  学号:20135317 成绩:             指导教师:娄嘉 ...

  7. Java课程实验报告 实验一 Java开发环境的熟悉

    北京电子科技学院(BESTI) 实     验    报     告 课程:Java程序设计 班级:1353 姓名:韩玉琪 学号:20135317 成绩:            指导教师:娄嘉鹏  实 ...

  8. JAVA课程实验报告 实验五 Java网络编程及安全

    北京电子科技学院(BESTI) 实     验    报     告 课程:Java程序设计  班级:1353  姓名:韩玉琪  学号:20135317 成绩:             指导教师:娄嘉 ...

  9. 第五周课程总结&实验报告(四)

    第五周课程总结 本周主要学习了 1.抽象类 抽象类的定义格式 abstract class抽象类名称{ 属性; 访问权限返回值类型方法名称(参数){ //普通方法 [return返回值]; } 访问权 ...

  10. c语言实验报告(四) 从键盘输入字符串a和字符串b,并在a串中的最小元素(不含结束符)后面插入字符串b.

    a串中最小元素后的字符被舍弃了. #include<stdio.h>#include<string.h>void main(){  int i,min=0;  char a[2 ...

随机推荐

  1. hdu1045Fire Net(经典dfs)

    Fire Net Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Su ...

  2. HTML 常见的 DOCTYPE 声明

    <!DOCTYPE> 声明必须是 HTML 文档的第一行,位于 <html> 标签之前. <!DOCTYPE> 声明不是 HTML 标签:它是指示 web 浏览器关 ...

  3. 180706-BigDecimal除法的精度问题

    BigDecimal除法的精度问题 在使用BigDecimal的除法时,遇到一个鬼畜的问题,本以为的精度计算,结果使用返回0,当然最终发现还是自己的使用姿势不对导致的,因此记录一下,避免后面重蹈覆辙 ...

  4. Java+Selenium 3.x 实现Web自动化 - 1.自动化准备

    (一)自动化准备 说明:本文主要记录了基于公司现有项目(一个电子商务平台),从0开始实现UI自动化的历程.从准备阶段,部分内容直接省略了基础知识,一切以最终做成自动化项目为目标,难免会有晦涩之处.文章 ...

  5. 阿里云ECS下Ubuntu 16.04系统安装python3.6.5 环境并设置为默认

    一.添加python3.6安装包并安装: 二.修改系统默认python版本为3.6: 三.安装并升级pip版本: 一.添加python3.6安装包并安装: sudo apt-get install s ...

  6. Http的请求和响应

    请求有客户端发起:可分为4个部分,请求方法(Requestmethod).请求的网址(Request URL).请求头(Request Headers).请求体(Request Body) 1.请求方 ...

  7. 【system.string】使用说明

    对象:system.string 说明:提供一系列针对字符串类型的操作 目录: 方法 返回 说明 system.string.isBlank( string ) [True | False]  检测参 ...

  8. lintcode First Unique Number In Stream

    First Unique Number In Stream 描述: Given a continuous stream of numbers, write a function that return ...

  9. Java学习 · 初识 面向对象深入二

    面向对象深入 1.            抽象类 a)     声明 i.           抽象方法和抽象类必须用abstract来修饰 ii.           没有方法体,不需要实现 b)  ...

  10. Java三种编译方式

    Java程序代码需要编译后才能在虚拟机中运行,编译涉及到非常多的知识层面:编译原理.语言规范.虚拟机规范.本地机器码优化等:了解编译过程有利于了解整个Java运行机制,不仅可以使得我们编写出更优秀的代 ...