20165324 Java实验五 网络编程与安全

一、实验报告封面

课程:Java程序设计 班级:1653班 姓名:何春江 学号:20165324

指导教师:娄嘉鹏 实验日期:2018年5月28日

实验时间:13:45 - 15:25 实验序号:24

实验名称:网络编程与安全

二、实验内容

任务一:两人一组结对编程:

  1. 参考http://www.cnblogs.com/rocedu/p/6766748.html#SECDSA
  2. 结对实现中缀表达式转后缀表达式的功能 MyBC.java
  3. 结对实现从上面功能中获取的表达式中实现后缀表达式求值的功能,调用MyDC.java
  4. 上传测试代码运行结果截图和码云链接

实现中缀表达式转后缀表达式

import java.util.Stack;
import java.util.StringTokenizer; public class MyBC {
/** constant for addition symbol */
private final char ADD = '+';
/** constant for subtraction symbol */
private final char SUBTRACT = '-';
/** constant for multiplication symbol */
private final char MULTIPLY = '*';
/** constant for division symbol */
private final char DIVIDE = '/';
/** the stack */
Stack<Integer> stack=new Stack<Integer>();; String expression;
public void setExpression(String str) {
expression=str;
}
public String changedWay() {
String changedExpression = "";
Stack signStack = new Stack();// 操作符栈
for (int i = 0; i < expression.length(); i++) {
char c = expression.charAt(i);
if (c >= '0' && c <= '9') {
changedExpression=changedExpression+c;
}
else if (c == '+' || c == '-' || c == '*' || c == '/') {
changedExpression=changedExpression+" ";//分隔数字
if (signStack.empty()) {
signStack.push(c);
}
else if (judgeValue(c) >= judgeValue((Character) signStack.peek())) {//优先级高于或等于,运算符号均进栈
signStack.push(c);
}
else {
changedExpression=changedExpression+(char)signStack.pop();
signStack.push(c);
}
}
else if (c=='(') {
signStack.push(c);
}
else if (c==')') {
while((char)signStack.peek()!='(') {
changedExpression=changedExpression+" "+signStack.pop();
}
signStack.pop();
}
}
while(!signStack.empty()){
changedExpression=changedExpression+" "+String.valueOf(signStack.pop());
}
return changedExpression;
} private static int judgeValue(char c) {
int value = 0;
switch (c) {
case '(':
value = 1;
break;
case '+':
case '-':
value = 2;
break;
case '*':
case '/':
value = 3;
break;
case ')':
value = 4;
default:
value = 0;
}
return value;
}
public int evaluate (String expr)
{//后缀表达式的运算方法
int op1, op2, result = 0;
String token;
StringTokenizer tokenizer = new StringTokenizer (expr);//使用StringTokenizer类分解String对象的字符序列,默认为空格符...
//此时tokenizer为一个分析器
while (tokenizer.hasMoreTokens()) {
token = tokenizer.nextToken();
if (isOperator(token))
{
op2 = (stack.pop()).intValue();//出栈
op1 = (stack.pop()).intValue();//出栈
result = evalSingleOp (token.charAt(0), op1, op2);//String对象第一个字符转换为char类型的方法为:str.charAt(0)
stack.push (new Integer(result));//进栈
}
else {
stack.push(new Integer(Integer.parseInt(token)));//进栈
}
}
return result;
}
private boolean isOperator (String token)
{
return ( token.equals("+") || token.equals("-") ||
token.equals("*") || token.equals("/") );
}
private int evalSingleOp (char operation, int op1, int op2)
{
int result = 0;
switch (operation)
{
case ADD:
result = op1 + op2;
break;
case SUBTRACT:
result = op1 - op2;
break;
case MULTIPLY:
result = op1 * op2;
break;
case DIVIDE:
result = op1 / op2;
}
return result;
}
}

参考资料:

任务二:两人一组结对编程:

  1. 参考http://www.cnblogs.com/rocedu/p/6766748.html#SECDSA
  2. 结对实现中缀表达式转后缀表达式的功能 MyBC.java
  3. 结对实现从上面功能中获取的表达式中实现后缀表达式求值的功能,调用MyDC.java
  4. 上传测试代码运行结果截图和码云链接
  • 获取本机IP地址:DESKTOP-HN1B8O2/172.30.2.248
InetAddress address_3=InetAddress.getLocalHost();
System.out.println(address_3.toString());
  • 结对伙伴的IP为:172.30.4.50 所选端口为:1111
  • 负责客服端的构建,实现代码为:
  • 选用AES加密算法
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
import java.util.*; public class Client_2Socket {
public static void main(String[] args) {
Socket Client_2Socket;
DataInputStream Client_2in=null;
DataOutputStream Client_2out=null;
String expr,str;
Scanner scanner=new Scanner(System.in);
System.out.println("请输入表达式:");
str=scanner.nextLine();
MyBC mybc=new MyBC();
mybc.setExpression(str);
expr=mybc.changedWay();
try {
Client_2Socket=new Socket("172.30.2.248",5353);
Client_2in=new DataInputStream(Client_2Socket.getInputStream());
Client_2out=new DataOutputStream(Client_2Socket.getOutputStream());
Client_2out.writeUTF(expr);
String s=Client_2in.readUTF();
System.out.println("服务器回复:\n"+s);
}
catch (Exception e) {
System.out.println("服务器已断开"+e);
}
}
}
  • 结对伙伴负责的服务器端代码为:
import java.io.*;
import java.net.*;
import java.util.*; public class Server_2 {
public static void main(String[] args) {
ServerSocket Server_2forClient_2=null;
Socket SocketOnServer_2=null;
DataOutputStream Server_2out=null;
DataInputStream Server_2in=null;
try {
Server_2forClient_2=new ServerSocket(5353);
}
catch (IOException e1) {
System.out.println(e1);
//e1.printStackTrace();
}
try {
System.out.println("等待客户端呼叫……");
SocketOnServer_2=Server_2forClient_2.accept();
Server_2out=new DataOutputStream(SocketOnServer_2.getOutputStream());
Server_2in=new DataInputStream(SocketOnServer_2.getInputStream());
String expr=Server_2in.readUTF();
System.out.println("服务器接收到表达式:"+expr);
int result;
MyBC mybc=new MyBC();
result=mybc.evaluate(expr);
Server_2out.writeUTF("后缀表达式:"+expr+",运算结果为:"+result);
Thread.sleep(500);
}
catch (Exception e2) {
System.out.println("客户端已断开"+e2);
}
}
}
  • 实验截图

任务三:加密结对编程:1人负责客户端,一人负责服务器

  1. 注意责任归宿,要会通过测试证明自己没有问题
  2. 基于Java Socket实现客户端/服务器功能,传输方式用TCP
  3. 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加密后通过网络把密文发送给服务器
  4. 服务器接收到后缀表达式表达式后,进行解密(和客户端协商密钥,可以用数组保存),然后调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
  5. 客户端显示服务器发送过来的结果
  6. 上传测试结果截图和码云链接
  • 思路:密文通过TCP传输,而AES密钥通过机密通道传输。
  • 负责客服端的构建,代码为:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
import java.util.*; public class Client_3 {
public static void main(String[] args) {
Socket Client_2Socket;
DataInputStream Client_2in=null;
DataOutputStream Client_2out=null;
String expr=null;
String str=null;
String Ciphertext=null;
Scanner scanner=new Scanner(System.in);
System.out.println("请输入表达式:");
str=scanner.nextLine();
MyBC mybc=new MyBC();
mybc.setExpression(str);
expr=mybc.changedWay();
try {
AES.produceAESKey();//生成AES密钥
byte[]cc= AES.EncryptionAES(expr);//需要传输的密文,数组形式传输。
Ciphertext = Base64.getEncoder().encodeToString(cc);//将加密后的密文由byte[]转换为String类型
} catch (Exception e) {
e.printStackTrace();
}
try {
Client_2Socket=new Socket("172.30.2.248",5300);
Client_2in=new DataInputStream(Client_2Socket.getInputStream());
Client_2out=new DataOutputStream(Client_2Socket.getOutputStream());
Client_2out.writeUTF(Ciphertext);
String s=Client_2in.readUTF();
System.out.println("服务器回复:\n"+s);
}
catch (Exception e) {
System.out.println("服务器已断开"+e);
}
}
}
  • 结对伙伴负责构建服务器,代码为:
import sun.security.krb5.internal.crypto.Aes128;

import java.io.*;
import java.net.*;
import java.util.*; public class Server_3 {
public static void main(String[] args) {
ServerSocket Server_2forClient_2=null;
Socket SocketOnServer_2=null;
DataOutputStream Server_2out=null;
DataInputStream Server_2in=null;
try {
Server_2forClient_2=new ServerSocket(5300);
}
catch (IOException e1) {
System.out.println(e1);
}
try {
System.out.println("等待客户端呼叫……");
SocketOnServer_2=Server_2forClient_2.accept();
Server_2out=new DataOutputStream(SocketOnServer_2.getOutputStream());
Server_2in=new DataInputStream(SocketOnServer_2.getInputStream());
String Ciphertext=Server_2in.readUTF();//密文
byte[] data= Base64.getDecoder().decode(Ciphertext);
String expr= AES.DecryptionAES(data);
System.out.println("服务器接收到表达式:"+expr);
int result;
MyBC mybc=new MyBC();
result=mybc.evaluate(expr);
Server_2out.writeUTF("后缀表达式:"+expr+",运算结果为:"+result);
Thread.sleep(500);
}
catch (Exception e2) {
System.out.println("客户端已断开"+e2);
}
}
}
  • 实验截图

任务四:密钥分发结对编程:1人负责客户端,一人负责服务器

  1. 注意责任归宿,要会通过测试证明自己没有问题
  2. 基于Java Socket实现客户端/服务器功能,传输方式用TCP
  3. 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加密通过网络把密文发送给服务器
  4. 客户端和服务器用DH算法进行3DES或AES算法的密钥交换
  5. 服务器接收到后缀表达式表达式后,进行解密,然后调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
  6. 客户端显示服务器发送过来的结果
  7. 上传测试结果截图和码云链接

DH算法相关链接:

  • DH算法原理

  • 密钥交换算法DH(Java实现)

  • 密钥交换实现过程:

    1. 由消息发送的一方构建密钥,这里由甲方构建密钥。
    2. 由构建密钥的一方向对方公布其公钥,这里由甲方向乙方发布公钥。
    3. 由消息接收的一方通过对方公钥构建自身密钥,这里由乙方使用甲方公钥构建乙方密钥。
    4. 由消息接收的一方向对方公布其公钥,这里由乙方向甲方公布公钥。
  • 使用密钥协定创建共享密钥截图:

  • 使用创建的共享密钥就可以对AES的密钥进行加解密。因为生成的共享密钥为DESede密钥类型,则使用DESede加解密模式,密钥为共享密钥其余不变。即将共享密钥保存于文件Key_DESede_DH.dat中即可。

  • 实现关键代码:

        SecretKeySpec k=new  SecretKeySpec(sb,"DESede");
FileOutputStream f=new FileOutputStream("A_Key_DESede_DH.dat");//指定产生密钥输出流文件
ObjectOutputStream b=new ObjectOutputStream(f);//将对象序列化,以流的方式进行处理
b.writeObject(k);//通过以对象序列化方式将密钥保存在文件中
  • 问题一:生成的共享密钥文件既然是DESede密钥类型,而DESede的长度密钥长度可以是112或168位。但生成的共享密钥的长度不为DESede规定的位数出现错误:java.security.InvalidKeyException: Invalid key length: 128 bytes
  • 问题一解决方法:使用AES密码机也不行..........产生同样的错误。

任务五:完整性校验结对编程:1人负责客户端,一人负责服务器

  1. 注意责任归宿,要会通过测试证明自己没有问题
  2. 基于Java Socket实现客户端/服务器功能,传输方式用TCP
  3. 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加密通过网络把密文和明文的MD5値发送给服务器
  4. 客户端和服务器用DH算法进行3DES或AES算法的密钥交换
  5. 服务器接收到后缀表达式表达式后,进行解密,解密后计算明文的MD5值,和客户端传来的MD5进行比较,一致则调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
  6. 客户端显示服务器发送过来的结果
  7. 上传测试结果截图和码云链接
  • 实验截图:

20165324 Java实验五 网络编程与安全的更多相关文章

  1. 2018-2019-2-20175323 java实验五 网络编程与安全

    20175323 java实验五 网络编程与安全 任务一 ①编写MyBC.java实现中缀表达式转后缀表达式的功能 ②编写MyDC.java实现从上面功能中获取的表达式中实现后缀表达式求值的功能 基本 ...

  2. Java实验五网络编程与安全

    实验五 网络编程与安全 实验准备 博客 活动一 两人一组结对编程: 0. 参考http://www.cnblogs.com/rocedu/p/6766748.html#SECDSA 1. 结对实现中缀 ...

  3. 20155324 《Java程序设计》实验五 网络编程与安全

    20155324 <Java程序设计>实验五 网络编程与安全 实验内容 任务一 编写MyBC.java实现中缀表达式转后缀表达式的功能 编写MyDC.java实现从上面功能中获取的表达式中 ...

  4. 20155326 《Java程序设计》实验五网络编程与安全实验报告

    20155326 <Java程序设计>实验五网络编程与安全实验报告 实验内容 任务一 1.两人一组结对编程: 参考http://www.cnblogs.com/rocedu/p/67667 ...

  5. #《JAVA程序设计》 20155214 实验五 网络编程与安全

    <JAVA程序设计> 20155214 实验五 网络编程与安全 实验内容 掌握Socket程序的编写: 掌握密码技术的使用: 设计安全传输系统. 实验要求 要求一 结对实现中缀表达式转后缀 ...

  6. 20155301 《Java程序设计》实验五网络编程与安全

    20155301 <Java程序设计>实验五网络编程与安全 实验内容 实验1: 两人一组结对编程:参考http://www.cnblogs.com/rocedu/p/6766748.htm ...

  7. 20155308 《Java程序设计》实验五 网络编程与安全

    20155308 <Java程序设计>实验五 网络编程与安全 实验内容 任务一 两人一组结对编程: 参考http://www.cnblogs.com/rocedu/p/6766748.ht ...

  8. 20155317 《Java程序设计》实验五网络编程与安全实验报告

    20155317 <Java程序设计>实验五网络编程与安全实验报告 遇到问题 在刚开始启动客户端或者服务端时,出现了一系列的错误情况,总是提示异常信息 后来经过询问同学,反应将端口号修改一 ...

  9. 20155320 《Java程序设计》实验五网络编程与安全实验报告

    20155320 <Java程序设计>实验五网络编程与安全实验报告 实验内容 实验一 1.两人一组结对编程: 参考http://www.cnblogs.com/rocedu/p/67667 ...

随机推荐

  1. imx6 android SD卡启动

    工作中需要将imx6的android系统从SD卡启动,所以就分析了MfgTool中的脚本,分析android的分区情况,并尝试自己操作,竟然成功了,记录于此. 参考文档 http://www.kanc ...

  2. oracle oci 调用 1

    http://blog.163.com/earth_of_fire/blog/static/1368943200791211622278/(总结) http://blog.163.com/earth_ ...

  3. poj3301--Texas Trip(最小正方形覆盖)

    题目链接:点击打开链接 题目大意:给出n个点的坐标.如今要求一个正方形,全然包围n个点.而且正方形面积最小,求最小的正方形面积. 表示不能理解为什么面积随着角度的变化是一个单峰的函数,等待大牛告诉一下 ...

  4. layDate/DatePicker日期时间空间

    真心不错,果断收藏了. 1.示例与效果 2.更多示例与皮肤 补充说明:My97DatePicker日期时间插件 的使用 1.示例与效果 2. 更多 常用的实例:WdatePicker下载 http:/ ...

  5. ulimit命令学习

    通过ulimit -n命令可以查看linux系统里打开文件描述符的最大值,一般缺省值是1024,对一台繁忙的服务器来说,这个值偏小,所以有必要重新设置linux系统里打开文件描述符的最大值.那么应该在 ...

  6. 禁止Apache显示目录索引的常见方法

    禁止Apache显示目录索引,禁止Apache显示目录结构列表,禁止Apache浏览目录,这是网上提问比较多的,其实都是一个意思.下面说下禁止禁止Apache显示目录索引的常见的3种方法. 要实现禁止 ...

  7. C++之运行时类型识别RTTI

     C++ Code  12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849 ...

  8. Android无线测试之—UiAutomator UiScrollable API介绍八

    设置滚动方向 一.设置滚动方向相关API 返回值 API 描述 UiScrollable setAsHorizontalList 设置滚动方向为水平滚动 UiScrollable setAsVerti ...

  9. Tiled地图编辑软件

    Tiled官网: http://www.mapeditor.org/ 一个比较简单好用的地图编辑软件.百度可以找到很多教程. 在Egret中,官网提供了Tiled的工具类,但是教程和文档极少...只能 ...

  10. VC/MFC中通过CWebPage类调用javascript函数(给js函数传参,并取得返回值)

    转自:http://www.cnblogs.com/javaexam2/archive/2012/07/14/2632959.html ①需要一个别人写好的类CWebPage,将其对于的两个文件Web ...