实验四

北京电子科技学院(BESTI)

             

课程:Java程序设计 班级:1351    姓名:黄君如  学号:20135117

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

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

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

实验名称:               

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

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

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

实验仪器:

名称

型号

数量

PC

MacBookAir

1

一、实验内容

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

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

3、然后集成代码,一人加密后通过TCP发送

加密使用AES或DES,加密密钥Key的发送,使用服务器的公钥加密,公钥算法用RSA或DH,发送信息的完整性验证使用MD5或SHA3

4、使用实验楼Git服务托管代码

 代码:

package client;

 

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

 

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

 

try {

//获取密钥生成器实例

KeyGenerator kg = KeyGenerator.getInstance("DESede");

//设置密钥长度

kg.init(168);

//生成对应的DESede密钥

SecretKey k = kg.generateKey();

//获取密钥的字节表示

byte[] ptext2 = k.getEncoded();

// String kstr=parseByte2HexStr(kb);

// 创建连接特定服务器的指定端口的Socket对象

Socket socket = new Socket("localhost", 12345);

// 获得从服务器端来的网络输入流

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(new File("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);

// System.out.println("c= "+c);

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 {

// stdin.close();

 

// in.close();

 

// out.close();

 

// socket.close();

}

}

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 com.junru.server;

 

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

 

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

 

ServerSocket sc = null;

 

Socket socket = null;

 

try {

 

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

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

 

// 解密模块,最后的keykb即明文;使用Dec_RSA代码

 

String aline2 = in.readLine();

 

BigInteger c = new BigInteger(aline2);

 

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

 

ObjectInputStream b = new ObjectInputStream(f);

 

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

 

BigInteger d = prk.getPrivateExponent();

 

BigInteger n = prk.getModulus();

 

// System.out.println("d= "+d);

 

// System.out.println("n= "+n);

 

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

 

// System.out.println("m= "+m);

 

byte[] keykb = m.toByteArray();

 

// String aline3=new String(mt,"UTF8");

 

// String aline3=parseByte2HexStr(byte buf[]);

 

// 源自SDec代码,用于解密

 

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

 

// FileInputStream f2=new FileInputStream("keykb1.dat");

 

// int num2=f2.available();

 

// byte[] keykb=new byte[num2];

 

// f2.read(keykb);

 

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;

 

}

 

}

 

 

二、总结

  1. 实验体会

    本次实验是java的最后一次实验,这次实验将java和密码学结合在一起,让我更看出了学科之间的融会贯通。老师提供的代码块看起来比较容易,但是修改、调试,并使它运行起来还是有一定的难度。说明以后要加强代码设计的思维训练,不要只专注于一部分的代码块,并要多对程序进行优化,才能更好地掌握知识。

     2.PSP时间

步骤

耗时

百分比

需求分析

36min

20%

设计

54min

30%

代码实现

36min

20%

测试

18min

10%

分析总结

36min

20%

 

posted @ 2015-06-11 23:23  20135117黄君如  阅读(163)  评论(0编辑  收藏  举报