2018-2019-2 20175204 张湲祯 实验五《网络编程与安全》实验报告
实验五《网络编程与安全》
一.实验内容:
1.网络编程与安全-1
任务详情
两人一组结对编程:
0.参考http://www.cnblogs.com/rocedu/p/6766748.html#SECDSA
1.结对实现中缀表达式转后缀表达式的功能 MyBC.java
2.结对实现从上面功能中获取的表达式中实现后缀表达式求值的功能,调用MyDC.java
3.上传测试代码运行结果截图和码云链接
2.网络编程与安全-2
结对编程:1人负责客户端,一人负责服务器
- 注意责任归宿,要会通过测试证明自己没有问题
- 基于Java Socket实现客户端/服务器功能,传输方式用TCP
- 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式通过网络发送给服务器
- 服务器接收到后缀表达式,调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
- 客户端显示服务器发送过来的结果
- 上传测试结果截图和码云链接
3.网络编程与安全-3
加密结对编程:1人负责客户端,一人负责服务器
- 注意责任归宿,要会通过测试证明自己没有问题
- 基于Java Socket实现客户端/服务器功能,传输方式用TCP
- 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加密后通过网络把密文发送给服务器
- 服务器接收到后缀表达式表达式后,进行解密(和客户端协商密钥,可以用数组保存),然后调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
- 客户端显示服务器发送过来的结果
- 上传测试结果截图和码云链接
4.网络编程与安全-4
密钥分发结对编程:1人负责客户端,一人负责服务器
- 注意责任归宿,要会通过测试证明自己没有问题
- 基于Java Socket实现客户端/服务器功能,传输方式用TCP
- 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加密通过网络把密文发送给服务器
- 客户端和服务器用DH算法进行3DES或AES算法的密钥交换
- 服务器接收到后缀表达式表达式后,进行解密,然后调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
- 客户端显示服务器发送过来的结果
- 上传测试结果截图和码云链接
5.网络编程与安全-5
实验五 网络编程与安全-5
完整性校验结对编程:1人负责客户端,一人负责服务器
- 注意责任归宿,要会通过测试证明自己没有问题
- 基于Java Socket实现客户端/服务器功能,传输方式用TCP
- 客户端让用户输入中缀表达式,然后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加密通过网络把密文和明文的MD5値发送给服务器
- 客户端和服务器用DH算法进行3DES或AES算法的密钥交换
- 服务器接收到后缀表达式表达式后,进行解密,解密后计算明文的MD5值,和客户端传来的MD5进行比较,一致则调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
- 客户端显示服务器发送过来的结果
- 上传测试结果截图和码云链接
二.实验步骤
1.任务一
1.使用栈对后缀表达式扫描:
-设置一个操作数栈,开始栈为空;
-从左到右扫描后缀表达式,遇操作数,进栈;
-若遇运算符,则从栈中退出两个元素,先退出的放到运算符的右边,后退出的放到运算符左边,运算后的结果再进栈,直到后缀表达式扫描完毕。
2.实验代码
/**
* MyDC
*
* @author 20175204
* @date 2019/5/28
*/
import java.util.StringTokenizer;
import java.util.Stack;
public class MyDC {
/** 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 */
private Stack stack;
public MyDC() {
stack = new Stack();
}
public int evaluate (String expr)
{
int op1, op2, result = 0;
String token;
StringTokenizer tokenizer = new StringTokenizer (expr);
while (tokenizer.hasMoreTokens())
{
token = tokenizer.nextToken();
//如果是运算符,调用isOperator
if (isOperator(token))
{
op2 = (stack.pop()).intValue();
//从栈中弹出操作数2
op1 = (stack.pop()).intValue();
//从栈中弹出操作数1
result = evalSingleOp(token.charAt(0),op1,op2);
//根据运算符和两个操作数调用evalSingleOp计算result;
stack.push(new Integer(result));
//计算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;
}
}
3.测试代码
import java.util.Scanner;
public class MyDCTester {
public static void main (String[] args) {
String expression, again;
int result;
try
{
Scanner in = new Scanner(System.in);
do
{
MyDC evaluator = new MyDC();
System.out.println ("Enter a valid postfix expression: ");
expression = in.nextLine();
result = evaluator.evaluate (expression);
System.out.println();
System.out.println ("That expression equals " + result);
System.out.print ("Evaluate another expression [Y/N]? ");
again = in.nextLine();
System.out.println();
}
while ("y".equalsIgnoreCase(again));
}
catch (Exception IOException)
{
System.out.println("Input exception reported");
}
}
}
4.实验截图
5.MyBC
-设立一个栈,存放运算符,首先栈为空;
-从左到右扫描中缀式,若遇到操作数,直接输出,并输出一个空格作为两个操作数的分隔符;
-若遇到运算符,则与栈顶比较,比栈顶级别高则进栈,否则退出栈顶元素并输出,然后输出一个空格作分隔符;
-若遇到左括号,进栈;若遇到右括号,则一直退栈输出,直到退到左括号止;
-当栈变成空时,输出的结果即为后缀表达式。
6.实验代码
/**
* MyDC
*
* @author 20175204
* @date 2019/5/28
*/
import java.util.StringTokenizer;
import java.util.Stack;
public class MyBC{
private Stack stack1;
public char Precede(char a,char b)
{
if(a=='#')
if(b!='#')
return '<';
else
return '=';
if(a==')')
return '>';
if(a=='(')
if(b!=')')
return '<';
else
return '=';
if(a=='/'||a=='*')
if(b!='(')
return '>';
else
return '<';
if(a=='-'||a=='+')
if(b!='*'&&b!='/'&&b!='(')
return '>';
else
return '<';
return '>';
}
public MyBC() {
stack1 = new Stack();
stack1.push('#');
}
public String turn(String expr) {
int result = 0;
String token;
char topelem,optr;
char[] exper1 = new char[100];
int i = 0;
StringTokenizer tokenizer = new StringTokenizer (expr);
while (tokenizer.hasMoreTokens())
{
token = tokenizer.nextToken();
if (isOperator(token))
{
topelem=stack1.peek();
optr = token.charAt(0);
if(Precede(topelem,optr)=='<')
{
stack1.push(optr);
}
else if(Precede(topelem,optr)=='=')
{
optr =stack1.pop();
exper1[i++] = optr;
exper1[i++] = ' ';
}
else if(Precede(topelem,optr)=='>')
{
optr =stack1.pop();
exper1[i++] = optr;
exper1[i++] = ' ';
}
}
else if(token.equals("(")) {
optr = token.charAt(0);
stack1.push(optr);
}
else if(token.equals(")")) {
optr = stack1.pop();
while(optr!='(')
{
exper1[i++] = optr;
exper1[i++] = ' ';
optr = stack1.pop();
}
}
else
{
optr = token.charAt(0);
//System.out.println(optr);
exper1[i++]=optr;
exper1[i++] = ' ';
}
}
while(!stack1.isEmpty())
{
optr = stack1.pop();
if(optr!='#'){
exper1[i++] = optr;
exper1[i++] = ' ';
}
}
return ToString(exper1);
}
//@Override
private boolean isOperator(String token)
{
return (token.equals("+") || token.equals("-") ||token.equals("*") || token.equals("/") );
}
public static String ToString(char[] exper1){
int length = exper1.length;
String str=" ";
for(int i=0;i
2.任务二
1.客户端
/**
* javaclient
*
* @author 20175204
* @date 2019/5/28
*/
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
public class javaClient {
public static final String IP_ADDR = "127.0.0.1";
public static final int PORT = 12345;
public static void main(String[] args) {
System.out.println("客户端启动...");
while (true) {
Socket socket = null;
try {
socket = new Socket(IP_ADDR, PORT);
DataInputStream input = new DataInputStream(socket.getInputStream());
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
System.out.print("请输入: \t");
String str = new BufferedReader(new InputStreamReader(System.in)).readLine();
MyBC turner = new MyBC();
String str1 = turner.turn(str);
int length=0,i=0;
while(str1.charAt(i)!='\0'){
length++;
i++;
}
String str2 = str1.substring(1,length-1);
out.writeUTF(str2);
String ret = input.readUTF();
System.out.println("服务器端返回过来的是: " + ret);
out.close();
input.close();
} catch (Exception e) {
System.out.println("客户端异常:" + e.getMessage());
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
socket = null;
System.out.println("客户端 finally 异常:" + e.getMessage());
}
}
}
}
}
}
2.服务器
/**
* javaclient
*
* @author 20175204
* @date 2019/5/28
*/
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class javaServer {
public static final int PORT = 12345;
public static void main(String[] args) {
System.out.println("服务器启动...\n");
javaServer server = new javaServer();
server.init();
}
public void init() {
try {
ServerSocket serverSocket = new ServerSocket(PORT);
while (true) {
Socket javaclient = serverSocket.accept();
new HandlerThread(javaclient);
}
} catch (Exception e) {
System.out.println("服务器异常: " + e.getMessage());
}
}
private class HandlerThread implements Runnable {
private Socket socket;
public HandlerThread(Socket client) {
socket = client;
new Thread(this).start();
}
public void run() {
try {
DataInputStream input = new DataInputStream(socket.getInputStream());
String clientInputStr = input.readUTF();
System.out.println("客户端发过来的内容:" + clientInputStr);
MyDC evalute = new MyDC();
int result = evalute.evaluate(clientInputStr);
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
System.out.print("计算结果:\t" + result);
System.out.print("\n");
out.writeUTF(String.valueOf(result));
out.close();
input.close();
} catch (Exception e) {
System.out.println("服务器 run 异常: " + e.getMessage());
} finally {
if (socket != null) {
try {
socket.close();
} catch (Exception e) {
socket = null;
System.out.println("服务端 finally 异常:" + e.getMessage());
}
}
}
}
}
}
3.任务三
1.Skey_DES
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
public class Skey_DES{
public static void key_DES()
throws Exception{
KeyGenerator kg=KeyGenerator.getInstance("DESede");
kg.init(168);
SecretKey k=kg.generateKey( );
FileOutputStream f=new FileOutputStream("key1.dat");
ObjectOutputStream b=new ObjectOutputStream(f);
b.writeObject(k);
}
}
2.Skey_kb
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.security.Key;
public class Skey_kb{
public static void key() throws Exception{
FileInputStream f=new FileInputStream("key1.dat");
ObjectInputStream b=new ObjectInputStream(f);
Key k=(Key)b.readObject( );
byte[ ] kb=k.getEncoded( );
FileOutputStream f2=new FileOutputStream("keykb1.dat");
f2.write(kb);
// 打印密钥编码中的内容
System.out.println("密钥为:");
for(int i=0;i
3.服务器
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Server1 {
public static final int PORT = 12345;//监听的端口号
public static void main(String[] args) {
System.out.println("服务器启动...\n");
Server1 server = new Server1();
server.init();
}
public void init() {
try {
ServerSocket serverSocket = new ServerSocket(PORT);
while (true) {
// 一旦有堵塞, 则表示服务器与客户端获得了连接
Socket client = serverSocket.accept();
// 处理这次连接
new HandlerThread(client);
}
} catch (Exception e) {
System.out.println("服务器异常: " + e.getMessage());
}
}
private class HandlerThread implements Runnable {
private Socket socket;
public HandlerThread(Socket client) {
socket = client;
new Thread(this).start();
}
public void run() {
try {
// 读取客户端数据
DataInputStream input = new DataInputStream(socket.getInputStream());
String clientInputStr = input.readUTF();//这里要注意和客户端输出流的写方法对应,否则会抛 EOFException
//处理客户端数据
System.out.println("客户端发过来的内容:" + clientInputStr);
MyDC evalute = new MyDC();
SDec sDec = new SDec();
int result = evalute.evaluate(clientInputStr);
// 向客户端回复信息
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
System.out.print("计算结果:\t");
// 发送键盘输入的一行
//String s = new BufferedReader(new InputStreamReader(System.in)).readLine();
out.writeUTF(String.valueOf(result));
out.close();
input.close();
} catch (Exception e) {
System.out.println("服务器 run 异常: " + e.getMessage());
} finally {
if (socket != null) {
try {
socket.close();
} catch (Exception e) {
socket = null;
System.out.println("服务端 finally 异常:" + e.getMessage());
}
}
}
}
}
}
4.客户端
import java.io.*;
import java.net.Socket;
public class Client1 {
public static final String IP_ADDR = "127.0.0.1";//服务器地址
public static final int PORT = 12345;//服务器端口号
public static void main(String[] args) {
System.out.println("客户端启动...");
while (true) {
Socket socket = null;
try {
//创建一个流套接字并将其连接到指定主机上的指定端口号
socket = new Socket(IP_ADDR, PORT);
//读取服务器端数据
DataInputStream input = new DataInputStream(socket.getInputStream());
//向服务器端发送数据
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
System.out.print("请输入: \t");
String str = new BufferedReader(new InputStreamReader(System.in)).readLine();
MyBC turner = new MyBC();
Skey_DES skey_des = new Skey_DES();
skey_des.key_DES();
Skey_kb skey_kb = new Skey_kb();
skey_kb.key();
/*产生密钥*/
SEnc sEnc = new SEnc();
String str1 = turner.turn(str);
int length = 0, i = 0;
while (str1.charAt(i) != '\0') {
length++;
i++;
}
String str2 = str1.substring(1, length - 1);
out.writeUTF(str2);
String ret = input.readUTF();
System.out.println("服务器端返回过来的是: " + ret);
// 如接收到 "OK" 则断开连接
/*if ("OK".equals(ret)) {
System.out.println("客户端将关闭连接");
Thread.sleep(500);
break;
}*/
out.close();
input.close();
} catch (Exception e) {
System.out.println("客户端异常:" + e.getMessage());
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
socket = null;
System.out.println("客户端 finally 异常:" + e.getMessage());
}
}
}
}
}
}
4.任务四
1.Keyagree
import java.io.*;
import java.math.*;
import java.security.*;
import java.security.spec.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import javax.crypto.interfaces.*;
public class KeyAgree{
public KeyAgree(){}
public static SecretKeySpec KeyAgree(String a,String b) throws Exception{
// 读取对方的DH公钥
FileInputStream f1=new FileInputStream(a);
ObjectInputStream b1=new ObjectInputStream(f1);
PublicKey pbk=(PublicKey)b1.readObject( );
//读取自己的DH私钥
FileInputStream f2=new FileInputStream(b);
ObjectInputStream b2=new ObjectInputStream(f2);
PrivateKey prk=(PrivateKey)b2.readObject( );
// 执行密钥协定
KeyAgreement ka=KeyAgreement.getInstance("DH");
ka.init(prk);
ka.doPhase(pbk,true);
//生成共享信息
byte[ ] s=ka.generateSecret();
byte []sb = new byte[24];
for(int i=0; i<24; i++)
sb[i] = s[i];
System.out.println("共享秘钥:");
for(int i=0;i
2.服务器
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.net.*;
public class Server2 {
public static void main(String[] args) {
ServerSocket serverForClient = null;
Socket socketOnServer = null;
DataOutputStream out = null;
DataInputStream in = null;
MyDC myDC = new MyDC();
try{
serverForClient = new ServerSocket(2010);
}catch (IOException e1){
System.out.println("服务器异常: "+e1);
}
try{
System.out.println("服务器启动...\n");
socketOnServer = serverForClient.accept();
out = new DataOutputStream(socketOnServer.getOutputStream());
in = new DataInputStream(socketOnServer.getInputStream());
//获取密文
String clength = in.readUTF();
byte []ctext = new byte[Integer.parseInt(clength)];
for(int i=0; i
3.客户端
import javax.crypto.spec.*;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
import java.util.Scanner;
public class Client2 {
public static void main(String[] args) {
Scanner inn = new Scanner(System.in);
Socket mysocket;
DataInputStream in = null;
DataOutputStream out = null;
try {
mysocket = new Socket("127.0.0.1", 2010);
in = new DataInputStream(mysocket.getInputStream());
out = new DataOutputStream(mysocket.getOutputStream());
KeyGenerator kg = KeyGenerator.getInstance("DESede");
kg.init(168);
SecretKey k = kg.generateKey();
byte[] kb = k.getEncoded();
System.out.println("请输入中缀表达式:");
String infix = inn.nextLine();
MyBC myBC = new MyBC();
String suffix = myBC.turn(infix);
System.out.println(suffix);
//中缀表达式加密
Cipher cp = Cipher.getInstance("DESede");
cp.init(Cipher.ENCRYPT_MODE, k);
byte ptext[] = suffix.getBytes("UTF8");
byte ctext[] = cp.doFinal(ptext);
out.writeUTF(ctext.length + "");
for (int i = 0; i < ctext.length; i++) {
out.writeUTF(ctext[i] + "");
}
//对密钥进行加密
KeyAgree keyAgree = new KeyAgree();
SecretKeySpec k1 = keyAgree.KeyAgree("Serverpub.dat","Clientpri.dat");
cp.init(Cipher.ENCRYPT_MODE, k1);
byte ckey[] = cp.doFinal(kb);
out.writeUTF(ckey.length + "");
for (int i = 0; i < ckey.length; i++) {
out.writeUTF(ckey[i] + "");
}
String result = in.readUTF();
System.out.println("服务器端返回过来的是:" + result);
Thread.sleep(500);
} catch (Exception e) {
System.out.println("客户端 finally 异常:" + e);
}
}
}
5.任务五
1.客户端
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.net.Socket;
import java.security.*;
import java.util.Scanner;
import java.net.*;
public class Client2 {
public static void main(String[] args) {
Socket mysocket;
DataInputStream in=null;
DataOutputStream out=null;
Scanner scanner = new Scanner(System.in);
try {
System.out.print("输入服务器的IP:");
String IP = scanner.nextLine();
InetAddress address=InetAddress.getByName(IP);
mysocket = new Socket(address, 2010);
in = new DataInputStream(mysocket.getInputStream());
out = new DataOutputStream(mysocket.getOutputStream());
Key_DH.DH("Lpub.dat","Lpri.dat");
FileInputStream my = new FileInputStream("Lpub.dat");
ObjectInputStream mypub = new ObjectInputStream(my);
Key kp = (Key) mypub.readObject();
ByteArrayOutputStream DH = new ByteArrayOutputStream();
ObjectOutputStream myDH = new ObjectOutputStream(DH);
myDH.writeObject(kp);
byte []pub = DH.toByteArray();
out.writeUTF(pub.length+"");
for(int i=0;i
2.服务器
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.*;
public class Server2 {
public static void main(String[] args) throws Exception {
ServerSocket serverForClient = null;
Socket socketOnServer = null;
DataOutputStream out = null;
DataInputStream in = null;
try {
serverForClient = new ServerSocket(2010);
} catch (IOException e) {
System.out.println(e);
}
System.out.println("等待客户呼叫");
try {
socketOnServer = serverForClient.accept();
out = new DataOutputStream(socketOnServer.getOutputStream());
in = new DataInputStream(socketOnServer.getInputStream());
Key_DH.DH("Wpub.dat","Wpri.dat");
int length = Integer.parseInt(in.readUTF());
byte cpub[] = new byte[length];
for(int i=0;i