20165321 實驗五 網絡編程與安全
阿新 • • 發佈:2018-06-03
功能 sock || clas CI 信息 cti tput decrypt
任務1
任務詳情
兩人一組結對編程:
- 參考http://www.cnblogs.com/rocedu/p/6766748.html#SECDSA
- 結對實現中綴表達式轉後綴表達式的功能 MyBC.java
- 結對實現從上面功能中獲取的表達式中實現後綴表達式求值的功能,調用MyDC.java
- 上傳測試代碼運行結果截圖和碼雲鏈接
代碼
由於myDC.java與myBC.java都不是主類,沒有辦法運行,所以只有上代碼了。
myDC.java
import java.util.*; 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<Integer> stack; public MyDC() { stack = new Stack<Integer>(); } public int evaluate (String expr) {//expr是算數表達式 int op1, op2, result = 0; String token; StringTokenizer tokenizer = new StringTokenizer (expr); while (tokenizer.hasMoreTokens()) { token = tokenizer.nextToken();//識別運算符 //補充代碼31-40行 //如果是運算符,調用isOperator if (isOperator(token))//如果是運算符,調用isOperator { char c[]=token.toCharArray(); op2=stack.pop();//從棧中彈出操作數2 op1=stack.pop();//從棧中彈出操作數1 result=evalSingleOp(c[0],op1,op2);//根據運算符和兩個操作數調用evalSingleOp計算result; stack.push(result);//計算result入棧; } else//如果是操作數 { stack.push(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; default: } return result; } }
myBC.java
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; break; default: value = 0; break; } 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; default: break; } return result; } }
任務2
任務詳情
結對編程:1人負責客戶端,一人負責服務器
- 註意責任歸宿,要會通過測試證明自己沒有問題
- 基於Java Socket實現客戶端/服務器功能,傳輸方式用TCP
- 客戶端讓用戶輸入中綴表達式,然後把中綴表達式調用MyBC.java的功能轉化為後綴表達式,把後綴表達式通過網絡發送給服務器
- 服務器接收到後綴表達式,調用MyDC.java的功能計算後綴表達式的值,把結果發送給客戶端
- 客戶端顯示服務器發送過來的結果
- 上傳測試結果截圖和碼雲鏈接
我完成的是服務器部分
運行截圖(服務器部分)
客戶端部分的截圖在我的結對搭檔的博客裏面
代碼
Server_2.java
import java.io.*; import java.net.*; import java.util.*; public class Server_2 { public static void main(String[] args) { final int port=5353; ServerSocket Server_2forClient_2=null; Socket SocketOnServer_2=null; DataOutputStream Server_2out=null; DataInputStream Server_2in=null; try { Server_2forClient_2=new ServerSocket(port); } 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 s=Server_2in.readUTF(); System.out.println("服務器接收到表達式:"+s); String expr; int result; MyBC mybc=new MyBC(); mybc.setExpression(s); expr=mybc.changedWay(); result=mybc.evaluate(expr); Server_2out.writeUTF("中綴表達式“"+s+"”轉後綴表達式“"+expr+",運算結果為:"+result); //Thread.sleep(500); } catch (Exception e2) { System.out.println("客戶端已斷開"+e2); } } }
Client_2.java
import java.io.*;
import java.net.*;
import java.util.*;
public class Client_2 {
public static void main(String[] args) {
final int port=5353;
final String host="172.30.4.50";
Socket Client_2Socket;
DataInputStream Client_2in=null;
DataOutputStream Client_2out=null;
String expr;
Scanner scanner=new Scanner(System.in);
System.out.println("請輸入表達式:");
expr=scanner.nextLine();
try {
Client_2Socket=new Socket(host,port);
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);
}
}
}
任務3
任務詳情
加密結對編程:1人負責客戶端,一人負責服務器
- 註意責任歸宿,要會通過測試證明自己沒有問題
- 基於Java Socket實現客戶端/服務器功能,傳輸方式用TCP
- 客戶端讓用戶輸入中綴表達式,然後把中綴表達式調用MyBC.java的功能轉化為後綴表達式,把後綴表達式用3DES或AES算法加密後通過網絡把密文發送給服務器
- 服務器接收到後綴表達式表達式後,進行解密(和客戶端協商密鑰,可以用數組保存),然後調用MyDC.java的功能計算後綴表達式的值,把結果發送給客戶端
- 客戶端顯示服務器發送過來的結果
- 上傳測試結果截圖和碼雲鏈接
截圖
代碼
Server_3.java
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);
//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 CipherText=Server_2in.readUTF();
String expr;
byte []data=Base64.getDecoder().decode(CipherText);
System.out.println("服務器接收到密文:"+data);
expr=AES.DecryptionAES(data);
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);
}
}
}
Client_3.java
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("10.1.1.175",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);
}
}
}
任務4
任務詳情
密鑰分發結對編程:1人負責客戶端,一人負責服務器
- 註意責任歸宿,要會通過測試證明自己沒有問題
- 基於Java Socket實現客戶端/服務器功能,傳輸方式用TCP
- 客戶端讓用戶輸入中綴表達式,然後把中綴表達式調用MyBC.java的功能轉化為後綴表達式,把後綴表達式用3DES或AES算法加密通過網絡把密文發送給服務器
- 客戶端和服務器用DH算法進行3DES或AES算法的密鑰交換
- 服務器接收到後綴表達式表達式後,進行解密,然後調用MyDC.java的功能計算後綴表達式的值,把結果發送給客戶端
- 客戶端顯示服務器發送過來的結果
- 上傳測試結果截圖和碼雲鏈接
代碼
Server_4.java
import java.io.*;
import java.net.*;
import java.util.*;
public class Server_4 {
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(5200);
}
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);
byte[] hh=AES_DH.DecryptionDES(data);
Server_2out.writeUTF("接受到使用DH算法生成的共享密鑰加密AES密鑰生成的密文為:");
for (int i=0;i<hh.length;i++) {
System.out.print(hh[i]+" ");
}
Thread.sleep(500);
}
catch (Exception e2) {
System.out.println("客戶端已斷開"+e2);
}
}
}
Client_4.java
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
import java.util.*;
public class Client_4 {
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;
System.out.println("傳輸使用DH算法生成的共享密鑰加密AES密鑰生成的密文");
try {
AES.produceAESKey();//生成AES密鑰
byte[]c= AES.changeWay();//AES密鑰,數組形式傳輸。
byte[]cc=AES_DH.EncryptionDES(c);//需要傳輸的使用DH算法生成的共享密鑰加密AES密鑰生成的密文,數組形式傳輸。
Ciphertext = Base64.getEncoder().encodeToString(cc);//將加密後的密文由byte[]轉換為String類型
} catch (Exception e) {
e.printStackTrace();
}
try {
Client_2Socket=new Socket("172.30.2.248",5200);
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);
}
}
}
AES_DH.java
import javax.crypto.Cipher;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.security.Key;
public class AES_DH {
//AES加密,返回密文。
public static byte[] EncryptionDES(byte[]data) throws Exception {
FileInputStream f = new FileInputStream("A_Key_DESede_DH.dat");
ObjectInputStream b = new ObjectInputStream(f);
Key k = (Key) b.readObject();//從文件中獲取密鑰
Cipher cp = Cipher.getInstance("AES");//創建密碼器
cp.init(Cipher.ENCRYPT_MODE, k);//初始化密碼器,第一個參數指定密碼器準備進行加密還是解密,第二個參數則傳入加密或解密所使用的密鑰。
byte ctext[] = cp.doFinal(data);//執行Cipher對象的doFinal()方法,該方法的參數中傳入待加密的明文,從而按照前面設置的算法與模式對明文加密。
System.out.println("共享密鑰加密完成!");
//FileOutputStream f2 = new FileOutputStream("Ciphertext.txt");//將密文保存於Ciphertext.dat中。
//f2.write(ctext);//處理加密結果
return ctext;
}
//DESede解密,信息保存。
public static byte[] DecryptionDES(byte[]data) throws Exception{
FileInputStream f = new FileInputStream("A_Key_DESede_DH.dat");
ObjectInputStream b = new ObjectInputStream(f);
Key k = (Key) b.readObject();//從文件中獲取密鑰
Cipher cp = Cipher.getInstance("AES");//創建密碼器
cp.init(Cipher.DECRYPT_MODE,k);
byte ctext[]=cp.doFinal(data);
//FileOutputStream ff=new FileOutputStream("Plaintext.txt");//將明文保存於Plaintext.dat中。
//ff.write(ctext);
System.out.println("共享密鑰解密完成!");
return ctext;
}
}
任務5
任務詳情
實驗五 網絡編程與安全-5
完整性校驗結對編程:1人負責客戶端,一人負責服務器
- 註意責任歸宿,要會通過測試證明自己沒有問題
- 基於Java Socket實現客戶端/服務器功能,傳輸方式用TCP
- 客戶端讓用戶輸入中綴表達式,然後把中綴表達式調用MyBC.java的功能轉化為後綴表達式,把後綴表達式用3DES或AES算法加密通過網絡把密文和明文的MD5値發送給服務器
- 客戶端和服務器用DH算法進行3DES或AES算法的密鑰交換
- 服務器接收到後綴表達式表達式後,進行解密,解密後計算明文的MD5值,和客戶端傳來的MD5進行比較,一致則調用MyDC.java的功能計算後綴表達式的值,把結果發送給客戶端
- 客戶端顯示服務器發送過來的結果
- 上傳測試結果截圖和碼雲鏈接
代碼
Server_5.java
import java.io.*;
import java.net.*;
import java.util.*;
public class Server_5 {
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(5555);
}
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("匹配成功");
Thread.sleep(5000);
}
catch (Exception e2) {
System.out.println("客戶端已斷開"+e2);
}
}
}
Client_5.java
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
import java.security.MessageDigest;
import java.util.*;
public class Client_5 {
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 {
MessageDigest m=MessageDigest.getInstance("MD5");//生成MessageDigest對象,使用靜態方法
m.update(expr.getBytes("UTF8"));//x為需要計算的字符串,update傳入的參數是字節類型或字節類型數組,對於字符串,需要先使用getBytes( )方法生成字符串數組。
byte ss[ ]=m.digest( );//計算的結果通過字節類型的數組返回。
String result="";
for (int i=0; i<ss.length; i++){
//處理計算結果
result+=Integer.toHexString((0x000000ff & ss[i]) |
0xffffff00).substring(6);
}
Client_2Socket=new Socket("172.30.2.248",5555);
Client_2in=new DataInputStream(Client_2Socket.getInputStream());
Client_2out=new DataOutputStream(Client_2Socket.getOutputStream());
Client_2out.writeUTF(result);
String s=Client_2in.readUTF();
System.out.println("服務器回復:\n"+s);
}
catch (Exception e) {
System.out.println("服務器已斷開"+e);
}
}
}
20165321 實驗五 網絡編程與安全