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. 011杰信-创建购销合同Excel报表系列-4-建立合同货物(修改,删除):合同货物表是购销合同表的子表

    前面的一篇文章做的是修改删除,这篇文章做的是合同货物的修改和删除. 业务功能如下:

  2. php -- PDO属性设置

    设置PDO在处理数据的过程中采用什么方式去处理 PDO::setAttribute:设置属性 PDO::getAttribute:获取属性 语法: bool PDO::setAttribute ( i ...

  3. 用原生Canvas写贪吃蛇及问题解决

    为了学习Canvas,写了这个小游戏贪吃蛇供自己和大家学习 Github: https://github.com/zhiyishou/Gsnake Play On: http://zhiyishou. ...

  4. 编程之美 set 3 最大公约数问题

    解法 1. f(x,y) = f(y, y%x) (y>0) 辗转相除法 2. 取模运算较为耗时, 将取模变成相减. 但对极端数据效果很差, 比如 gcd(1000,1) 3. 分析公约数的特点 ...

  5. 【BZOJ4517】[Sdoi2016]排列计数 组合数+错排

    [BZOJ4517][Sdoi2016]排列计数 Description 求有多少种长度为 n 的序列 A,满足以下条件: 1 ~ n 这 n 个数在序列中各出现了一次 若第 i 个数 A[i] 的值 ...

  6. 《从零开始学Swift》学习笔记(Day 65)——Cocoa Touch设计模式及应用之选择器

    原创文章,欢迎转载.转载请注明:关东升的博客 实现目标与动作关联使用UIControl类addTarget(_:action:forControlEvents:)方法,示例代码如下: button.a ...

  7. LeetCode 笔记系列16.1 Minimum Window Substring [从O(N*M), O(NlogM)到O(N),人生就是一场不停的战斗]

    题目: Given a string S and a string T, find the minimum window in S which will contain all the charact ...

  8. Angular2+学习第3篇 基本知识-组件

    一.插值表达式 基本用法与ng1一样. 可以使用 Angular 内置的 json 管道,来显示对象信息,管道用来格式化数据 import { Component } from '@angular/c ...

  9. HTML5跨平台开发环境配置

    http://hi.baidu.com/kuntakinte/item/1bbd3759b4901a3695eb050c

  10. 简单安装与配置mysql数据库(绿色版)

    目录 绿色版下载 mysql绿色版(5.7版本的安装与配置) 绿色版下载: mysql官网下载地址:https://www.oracle.com/index.html mysql绿色版(5.7版本的安 ...