20175212童皓楨 實驗五 網絡編程與安全
實驗內容
結對編程,完成網絡編程與安全相關內容
實驗步驟
任務一
任務一要求:
結對實現中綴表達式轉后綴表達式的功能 MyBC.java結對實現從上面功能中獲取的表達式中實現后綴表達式求值的功能,調用MyDC.java
實驗過程:
由中綴式求得后綴式可以使用棧,偽代碼如下: - 設立一個棧,存放運算符,首先棧為空;
- 從左到右掃描中綴式,若遇到操作數,直接輸出,并輸出一個空格作為兩個操作數的分隔符;
- 若遇到運算符,則與棧頂比較,比棧頂級別高則進棧,否則退出棧頂元素并輸出,然后輸出一個空格作分隔符;
- 若遇到左括號,進棧;若遇到右括號,則一直退棧輸出,直到退到左括號止。
- 當棧變成空時,輸出的結果即為后綴表達式
后綴表達式求值偽代碼如下:
- 設置一個操作數棧,開始棧為空;
- 從左到右遍歷后綴表達式,遇操作數,進棧;
- 若遇運算符,則從棧中退出兩個元素,先退出的放到運算符的右邊,后退出的放到運算符左邊,運算后的結果再進棧,直到后綴表達式遍歷完畢。
- 重復以上步驟,直至后綴表達式結束,棧中最后一個數字就是表達式的值。
實驗代碼:
public class MyBC {private Stack theStack;private String input;private String output = "";public MyBC(String in) {input = in;int stackSize = input.length();theStack = new Stack(stackSize);}public String doTrans() {for (int j = 0; j < input.length(); j++) {char ch = input.charAt(j);switch (ch) {case '+':case '-':getOp(ch, 1);break;case '*':case '/':getOp(ch, 2);break;case '(':theStack.push(ch);break;case ')':getParen(ch);break;default:output = output + ch;break;}}while (!theStack.isEmpty()) {output = output + theStack.pop();}return output;}public void getOp(char opThis, int prec1) {while (!theStack.isEmpty()) {char opTop = theStack.pop();if (opTop == '(') {theStack.push(opTop);break;} else {int prec2;if (opTop == '+' || opTop == '-')prec2 = 1;elseprec2 = 2;if (prec2 < prec1) {theStack.push(opTop);break;} elseoutput = output + opTop;}}theStack.push(opThis);}public void getParen(char ch) {while (!theStack.isEmpty()) {char chx = theStack.pop();if (chx == '(')break;elseoutput = output + chx;}}class Stack {private int maxSize;private char[] stackArray;private int top;public Stack(int max) {maxSize = max;stackArray = new char[maxSize];top = -1;}public void push(char j) {stackArray[++top] = j;}public char pop() {return stackArray[top--];}public char peek() {return stackArray[top];}public boolean isEmpty() {return (top == -1);}}
}
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<Integer> stack;public MyDC() {stack = new Stack<Integer>();}public int evaluate (String str){int op1, op2, result = 0;String token;StringTokenizer tokenizer = new StringTokenizer (str);while (tokenizer.hasMoreTokens()){token = tokenizer.nextToken();//如果是運算符,調用isOperatorif (isOperator(token)) {//從棧中彈出操作數2op2 = stack.pop();//從棧中彈出操作數1op1 = stack.pop();//根據運算符和兩個操作數調用evalSingleOp計算result;result=evalSingleOp(token.charAt(0), op1, op2);//計算result入棧;stack.push(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;}return result;}
}
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<Integer> stack;public MyDC() {stack = new Stack<Integer>();}public int evaluate (String str){int op1, op2, result = 0;String token;StringTokenizer tokenizer = new StringTokenizer (str);while (tokenizer.hasMoreTokens()){token = tokenizer.nextToken();//如果是運算符,調用isOperatorif (isOperator(token)) {//從棧中彈出操作數2op2 = stack.pop();//從棧中彈出操作數1op1 = stack.pop();//根據運算符和兩個操作數調用evalSingleOp計算result;result=evalSingleOp(token.charAt(0), op1, op2);//計算result入棧;stack.push(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;}return result;}
}
運行結果:
任務二
任務二要求:
1人負責客戶端,一人負責服務器
注意責任歸宿,要會通過測試證明自己沒有問題基于Java Socket實現客戶端/服務器功能,傳輸方式用TCP客戶端讓用戶輸入中綴表達式,然后把中綴表達式調用MyBC.java的功能轉化為后綴表達式,把后綴表達式通過網絡發(fā)送給服務器服務器接收到后綴表達式,調用MyDC.java的功能計算后綴表達式的值,把結果發(fā)送給客戶端客戶端顯示服務器發(fā)送過來的結果- 提交代碼運行截圖和碼云Git鏈接 實驗過程
import java.net.*;public class Address {public static void main(String[] args) throws UnknownHostException {InetAddress net = InetAddress.getLocalHost();System.out.println(net.toString());}}
import java.io.*;
import java.net.*;public class Client {public static void main(String args[]) {System.out.println("客戶端啟動...");//while (true) {Socket mysocket;DataInputStream in = null;DataOutputStream out = null;try {mysocket = new Socket("192.168.56.1", 2019);in = new DataInputStream(mysocket.getInputStream());out = new DataOutputStream(mysocket.getOutputStream());System.out.println("請輸入:");String str = new BufferedReader(new InputStreamReader(System.in)).readLine();MyBC turner = new MyBC(str);String infix;infix=turner.doTrans();StringBuilder newInfix = new StringBuilder(infix.replace(" ",""));for (int i = 1; i < infix.length()+(i+1)/2 ; i=i+2) {newInfix.insert(i," ");}out.writeUTF(newInfix.toString());//調用toString()方法,返回newInflx的String值,以便調用writeUTF方法String s = in.readUTF(); //in讀取信息,堵塞狀態(tài)System.out.println("客戶收到服務器的回答:" + s);Thread.sleep(500);//在500毫秒數讓當前正在執(zhí)行的線程休眠} catch (Exception e) {System.out.println("服務器已斷開" + e);}//}}
}
import java.io.*;
import java.net.*;public class Server {public static void main(String[] args) throws IOException {int answer;//while (true) {ServerSocket serverForClient = null;Socket socketOnServer = null;DataOutputStream out = null;DataInputStream in = null;try {serverForClient = new ServerSocket(2019);} catch (IOException e1) {System.out.println(e1);}try {System.out.println("等待客戶呼叫");socketOnServer = serverForClient.accept(); //堵塞狀態(tài),除非有客戶呼叫out = new DataOutputStream(socketOnServer.getOutputStream());in = new DataInputStream(socketOnServer.getInputStream());String s = in.readUTF(); // in讀取信息,堵塞狀態(tài)System.out.println("服務器收到客戶的提問:" + s);MyDC myDC = new MyDC();answer = myDC.evaluate(s);out.writeUTF(answer + "");Thread.sleep(500);} catch (Exception e) {System.out.println("客戶已斷開" + e);}//}}
}
運行結果:
任務三
任務三要求:
1人負責客戶端,一人負責服務器
注意責任歸宿,要會通過測試證明自己沒有問題基于Java Socket實現客戶端/服務器功能,傳輸方式用TCP客戶端讓用戶輸入中綴表達式,然后把中綴表達式調用MyBC.java的功能轉化為后綴表達式,把后綴表達式用3DES或AES算法加密后通過網絡把密文發(fā)送給服務器服務器接收到后綴表達式表達式后,進行解密(和客戶端協商密鑰,可以用數組保存),然后調用MyDC.java的功能計算后綴表達式的值,把結果發(fā)送給客戶端客戶端顯示服務器發(fā)送過來的結果 import javax.crypto.Cipher;
import java.io.*;
import java.net.*;
import java.security.Key;public class Client {public static void main(String args[]) {System.out.println("客戶端啟動...");//while (true) {Socket mysocket;DataInputStream in = null;DataOutputStream out = null;try {mysocket = new Socket("192.168.56.1", 2019);in = new DataInputStream(mysocket.getInputStream());out = new DataOutputStream(mysocket.getOutputStream());System.out.println("請輸入:");String str = new BufferedReader(new InputStreamReader(System.in)).readLine();MyBC turner = new MyBC(str);String infix;infix=turner.doTrans();StringBuilder newInfix = new StringBuilder(infix.replace(" ",""));for (int i = 1; i < infix.length()+(i+1)/2 ; i=i+2) {newInfix.insert(i," ");}String str1=newInfix.toString();//DES加密String a=null;FileInputStream f=new FileInputStream("key1.dat");ObjectInputStream b=new ObjectInputStream(f);Key k=(Key)b.readObject( );Cipher cp=Cipher.getInstance("DESede");cp.init(Cipher.ENCRYPT_MODE, k);byte ptext[]=str1.getBytes("UTF8");byte ctext[]=cp.doFinal(ptext);for(int i=0;i<ctext.length;i++){a+=String.valueOf(ctext[i]);}FileOutputStream f2=new FileOutputStream("SEnc.dat");f2.write(ctext);out.writeUTF(a);//調用toString()方法,返回newInflx的String值,以便調用writeUTF方法String s = in.readUTF(); //in讀取信息,堵塞狀態(tài)System.out.println("客戶收到服務器的回答:" + s);Thread.sleep(500);//在500毫秒數讓當前正在執(zhí)行的線程休眠} catch (Exception e) {System.out.println("服務器已斷開" + e);}//}}
}
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.net.*;public class Server {public static void main(String[] args) throws IOException {int answer;//while (true) {ServerSocket serverForClient = null;Socket socketOnServer = null;DataOutputStream out = null;DataInputStream in = null;try {serverForClient = new ServerSocket(2019);} catch (IOException e1) {System.out.println(e1);}try {System.out.println("等待客戶呼叫");socketOnServer = serverForClient.accept(); //堵塞狀態(tài),除非有客戶呼叫out = new DataOutputStream(socketOnServer.getOutputStream());in = new DataInputStream(socketOnServer.getInputStream());String s = in.readUTF(); // in讀取信息,堵塞狀態(tài)// 獲取密文FileInputStream f=new FileInputStream("SEnc.dat");int num=f.available();byte[ ] ctext=new byte[num];f.read(ctext);// 獲取密鑰FileInputStream f2=new FileInputStream("keykb1.dat");int num2=f2.available();byte[ ] keykb=new byte[num2];f2.read(keykb);SecretKeySpec 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);MyDC myDC = new MyDC();answer = myDC.evaluate(p);out.writeUTF(answer + "");Thread.sleep(500);} catch (Exception e) {System.out.println("客戶已斷開" + e);}//}}
}
import java.io.*;
import javax.crypto.*;
public class Skey_DES{public static void main(String args[])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);}
}
import java.io.*;
import java.security.*;
public class Skey_kb{public static void main(String args[]) 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);// 打印密鑰編碼中的內容for(int i=0;i<kb.length;i++){System.out.print(kb[i]+",");}}
}
運行結果:
任務四
任務四要求:
1人負責客戶端,一人負責服務器
注意責任歸宿,要會通過測試證明自己沒有問題基于Java Socket實現客戶端/服務器功能,傳輸方式用TCP客戶端讓用戶輸入中綴表達式,然后把中綴表達式調用MyBC.java的功能轉化為后綴表達式,把后綴表達式用3DES或AES算法加密通過網絡把密文發(fā)送給服務器客戶端和服務器用DH算法進行3DES或AES算法的密鑰交換服務器接收到后綴表達式表達式后,進行解密,然后調用MyDC.java的功能計算后綴表達式的值,把結果發(fā)送給客戶端客戶端顯示服務器發(fā)送過來的結果 import java.net.*;
import java.io.*;
import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;
public class Client {public static void main(String []args) throws Exception{try{// 1、創(chuàng)建客戶端Socket,指定服務器地址和端口Socket socket=new Socket("192.168.56.1",2019);System.out.println("客戶端成功啟動,等待客戶端呼叫");// 2、獲取輸出流,向服務器端發(fā)送信息// 向本機的10001端口發(fā)出客戶請求System.out.println("請輸入中綴表達式:");BufferedReader br = new BufferedReader(new InputStreamReader(System.in));// 由系統標準輸入設備構造BufferedReader對象PrintWriter write = new PrintWriter(socket.getOutputStream());// 由Socket對象得到輸出流,并構造PrintWriter對象//3、獲取輸入流,并讀取服務器端的響應信息BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));// 由Socket對象得到輸入流,并構造相應的BufferedReader對象String readline, infix, expression;readline = br.readLine(); // 從系統標準輸入讀入一字符串MyBC theTrans = new MyBC(readline);infix = theTrans.doTrans();StringBuilder newInfix = new StringBuilder(infix.replace(" ",""));for (int i = 1; i < infix.length()+(i+1)/2 ; i=i+2) {newInfix.insert(i," ");}System.out.println("后綴表達式: " + newInfix);expression=newInfix.toString();// 讀取對方的DH公鑰FileInputStream f1=new FileInputStream("Bpub");ObjectInputStream b1=new ObjectInputStream(f1);PublicKey pbk=(PublicKey)b1.readObject( );//讀取自己的DH私鑰FileInputStream f2=new FileInputStream("Asec");ObjectInputStream b2=new ObjectInputStream(f2);PrivateKey prk=(PrivateKey)b2.readObject( );// 執(zhí)行密鑰協定KeyAgreement ka=KeyAgreement.getInstance("DH");ka.init(prk);ka.doPhase(pbk,true);//生成共享信息byte[ ] sb=ka.generateSecret();//System.out.println(sb.length);byte[]ssb=new byte[24];for(int i=0;i<24;i++)ssb[i]=sb[i];Key k=new SecretKeySpec(ssb,"DESede");Cipher cp=Cipher.getInstance("DESede");cp.init(Cipher.ENCRYPT_MODE, k);byte ptext[]=expression.getBytes("UTF-8");byte ctext[]=cp.doFinal(ptext);String Str=new String(ctext,"ISO-8859-1");while (!readline.equals("end")) {// 若從標準輸入讀入的字符串為 "end"則停止循環(huán)write.println(Str);// 將從系統標準輸入讀入的字符串輸出到Serverwrite.flush();// 刷新輸出流,使Server馬上收到該字符串System.out.println("加密后的信息:" + Str);// 在系統標準輸出上打印讀入的字符串System.out.println("服務器發(fā)來的信息:" + in.readLine());// 從Server讀入一字符串,并打印到標準輸出上readline = br.readLine(); // 從系統標準輸入讀入一字符串} // 繼續(xù)循環(huán)//4、關閉資源write.close(); // 關閉Socket輸出流in.close(); // 關閉Socket輸入流socket.close(); // 關閉Socket}catch (Exception e){System.out.println(e);//輸出異常}finally{}}
}
import java.net.*;
import java.io.*;
import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;
public class Server{public static void main(String []args) throws Exception{ServerSocket sc = null;Socket socket=null;try{MyDC evaluator = new MyDC();sc= new ServerSocket(2019);//創(chuàng)建服務器套接字//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);//使用服務器端RSA的私鑰對DES的密鑰進行解密String aline2=in.readLine();System.out.println("客戶端發(fā)來的信息為:"+aline2);// 獲取密鑰byte[]ctext=aline2.getBytes("ISO-8859-1");// 讀取對方的DH公鑰FileInputStream f1=new FileInputStream("Bpub");ObjectInputStream b1=new ObjectInputStream(f1);PublicKey pbk=(PublicKey)b1.readObject( );//讀取自己的DH私鑰FileInputStream f2=new FileInputStream("Asec");ObjectInputStream b2=new ObjectInputStream(f2);PrivateKey prk=(PrivateKey)b2.readObject( );// 執(zhí)行密鑰協定KeyAgreement ka=KeyAgreement.getInstance("DH");ka.init(prk);ka.doPhase(pbk,true);//生成共享信息byte[ ] sb=ka.generateSecret();byte[]ssb=new byte[24];for(int i=0;i<24;i++)ssb[i]=sb[i];SecretKeySpec k=new SecretKeySpec(ssb,"DESede");// 解密Cipher cp=Cipher.getInstance("DESede");cp.init(Cipher.DECRYPT_MODE, k);byte []ptext=cp.doFinal(ctext);// 顯示明文String p=new String(ptext,"UTF8");int ans = evaluator.evaluate(p);out.println(ans);System.out.println("Result = "+ans);} catch (Exception e) {System.out.println(e);}}//十六進制和十進制轉換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;}
}
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 static void main(String args[ ]) throws Exception{// 讀取對方的DH公鑰FileInputStream f1=new FileInputStream("Bpub");ObjectInputStream b1=new ObjectInputStream(f1);PublicKey pbk=(PublicKey)b1.readObject( );
//讀取自己的DH私鑰FileInputStream f2=new FileInputStream("Asec");ObjectInputStream b2=new ObjectInputStream(f2);PrivateKey prk=(PrivateKey)b2.readObject( );// 執(zhí)行密鑰協定KeyAgreement ka=KeyAgreement.getInstance("DH");ka.init(prk);ka.doPhase(pbk,true);//生成共享信息byte[ ] sb=ka.generateSecret();for(int i=0;i<sb.length;i++){System.out.print(sb[i]+",");}SecretKeySpec k=new SecretKeySpec(sb,"DESede");}
}
import java.io.*;
import java.math.*;
import java.security.*;
import java.security.spec.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import javax.crypto.interfaces.*;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 Key_DH{//三個靜態(tài)變量的定義從
// C:\j2sdk-1_4_0-doc\docs\guide\security\jce\JCERefGuide.html
// 拷貝而來
// The 1024 bit Diffie-Hellman modulus values used by SKIPprivate static final byte skip1024ModulusBytes[] = {(byte)0xF4, (byte)0x88, (byte)0xFD, (byte)0x58,(byte)0x4E, (byte)0x49, (byte)0xDB, (byte)0xCD,(byte)0x20, (byte)0xB4, (byte)0x9D, (byte)0xE4,(byte)0x91, (byte)0x07, (byte)0x36, (byte)0x6B,(byte)0x33, (byte)0x6C, (byte)0x38, (byte)0x0D,(byte)0x45, (byte)0x1D, (byte)0x0F, (byte)0x7C,(byte)0x88, (byte)0xB3, (byte)0x1C, (byte)0x7C,(byte)0x5B, (byte)0x2D, (byte)0x8E, (byte)0xF6,(byte)0xF3, (byte)0xC9, (byte)0x23, (byte)0xC0,(byte)0x43, (byte)0xF0, (byte)0xA5, (byte)0x5B,(byte)0x18, (byte)0x8D, (byte)0x8E, (byte)0xBB,(byte)0x55, (byte)0x8C, (byte)0xB8, (byte)0x5D,(byte)0x38, (byte)0xD3, (byte)0x34, (byte)0xFD,(byte)0x7C, (byte)0x17, (byte)0x57, (byte)0x43,(byte)0xA3, (byte)0x1D, (byte)0x18, (byte)0x6C,(byte)0xDE, (byte)0x33, (byte)0x21, (byte)0x2C,(byte)0xB5, (byte)0x2A, (byte)0xFF, (byte)0x3C,(byte)0xE1, (byte)0xB1, (byte)0x29, (byte)0x40,(byte)0x18, (byte)0x11, (byte)0x8D, (byte)0x7C,(byte)0x84, (byte)0xA7, (byte)0x0A, (byte)0x72,(byte)0xD6, (byte)0x86, (byte)0xC4, (byte)0x03,(byte)0x19, (byte)0xC8, (byte)0x07, (byte)0x29,(byte)0x7A, (byte)0xCA, (byte)0x95, (byte)0x0C,(byte)0xD9, (byte)0x96, (byte)0x9F, (byte)0xAB,(byte)0xD0, (byte)0x0A, (byte)0x50, (byte)0x9B,(byte)0x02, (byte)0x46, (byte)0xD3, (byte)0x08,(byte)0x3D, (byte)0x66, (byte)0xA4, (byte)0x5D,(byte)0x41, (byte)0x9F, (byte)0x9C, (byte)0x7C,(byte)0xBD, (byte)0x89, (byte)0x4B, (byte)0x22,(byte)0x19, (byte)0x26, (byte)0xBA, (byte)0xAB,(byte)0xA2, (byte)0x5E, (byte)0xC3, (byte)0x55,(byte)0xE9, (byte)0x2F, (byte)0x78, (byte)0xC7};// The SKIP 1024 bit modulusprivate static final BigInteger skip1024Modulus= new BigInteger(1, skip1024ModulusBytes);// The base used with the SKIP 1024 bit modulusprivate static final BigInteger skip1024Base = BigInteger.valueOf(2);public static void main(String args[ ]) throws Exception{DHParameterSpec DHP=new DHParameterSpec(skip1024Modulus,skip1024Base);KeyPairGenerator kpg= KeyPairGenerator.getInstance("DH");kpg.initialize(DHP);KeyPair kp=kpg.genKeyPair();PublicKey pbk=kp.getPublic();PrivateKey prk=kp.getPrivate();// 保存公鑰FileOutputStream f1=new FileOutputStream("Bpub");ObjectOutputStream b1=new ObjectOutputStream(f1);b1.writeObject(pbk);// 保存私鑰FileOutputStream f2=new FileOutputStream("Asec");ObjectOutputStream b2=new ObjectOutputStream(f2);b2.writeObject(prk);}
}
運行結果:
任務五
完整性校驗結對編程:
1人負責客戶端,一人負責服務器
注意責任歸宿,要會通過測試證明自己沒有問題基于Java Socket實現客戶端/服務器功能,傳輸方式用TCP客戶端讓用戶輸入中綴表達式,然后把中綴表達式調用MyBC.java的功能轉化為后綴表達式,把后綴表達式用3DES或AES算法加密通過網絡把密文和明文的MD5値發(fā)送給服務器客戶端和服務器用DH算法進行3DES或AES算法的密鑰交換服務器接收到后綴表達式表達式后,進行解密,解密后計算明文的MD5值,和客戶端傳來的MD5進行比較,一致則調用MyDC.java的功能計算后綴表達式的值,把結果發(fā)送給客戶端客戶端顯示服務器發(fā)送過來的結果上傳測試結果截圖和碼云鏈接 import java.net.*;
import java.io.*;
import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import java.security.interfaces.*;
import java.math.*;public class Server {public static void main(String args[]) throws Exception {ServerSocket link = null;Socket socket = null;try {link = new ServerSocket(3);// 創(chuàng)建服務器套接字//System.out.println("端口號:" + link.getLocalPort());System.out.println("等待客戶連接");socket = link.accept(); // 等待客戶端連接System.out.println("已經建立連接");//獲得網絡輸入流對象的引用BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));//獲得網絡輸出流對象的引用PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);// 使用服務器端RSA的私鑰對DES的密鑰進行解密String line = in.readLine();BigInteger cipher = new BigInteger(line);FileInputStream f = new FileInputStream("Skey_RSA_priv.dat");ObjectInputStream b = new ObjectInputStream(f);RSAPrivateKey prk = (RSAPrivateKey) b.readObject();BigInteger d = prk.getPrivateExponent();BigInteger n = prk.getModulus();//mod nBigInteger m = cipher.modPow(d, n);//m=d (mod n)System.out.println("d= " + d);System.out.println("n= " + n);System.out.println("m= " + m);byte[] keykb = m.toByteArray();// 使用DES對密文進行解密String readline = in.readLine();//讀取客戶端傳送來的數據FileInputStream f2 = new FileInputStream("keykb1.dat");int num2 = f2.available();byte[] ctext = parseHexStr2Byte(readline);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); //打印解密結果// 使用Hash函數檢測明文完整性String aline3 = in.readLine();String x = p;MessageDigest m2 = MessageDigest.getInstance("MD5");//使用MD5算法返回實現指定摘要算法的 MessageDigest對象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("MD5:"+result);if (aline3.equals(result)) {System.out.println("匹配成功");}MyDC evaluator = new MyDC();int _result = evaluator.value(p);out.println(_result);out.close();in.close();link.close();} catch (Exception e) {System.out.println(e);}}//二進制轉換成十六進制,防止byte[]數字轉換成string類型時造成的數據損失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;}}
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 Client {public static void main(String args[]) throws Exception {try {KeyGenerator kg = KeyGenerator.getInstance("DESede");kg.init(168);SecretKey k = kg.generateKey();byte[] ptext2 = k.getEncoded();Socket socket = new Socket("127.0.0.1", 3);System.out.println("客戶端成功啟動,等待客戶端呼叫");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));//RSA算法,使用服務器端的公鑰對DES的密鑰進行加密FileInputStream f3 = new FileInputStream("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);String cs = c.toString();out.println(cs); // 通過網絡將加密后的秘鑰傳送到服務器System.out.println("請輸入中綴表達式:");//用DES加密明文得到密文String s = stdin.readLine(); // 從鍵盤讀入待發(fā)送的數據String postfix = MyBC.toPostfix(s);Cipher cp = Cipher.getInstance("DESede");cp.init(Cipher.ENCRYPT_MODE, k);byte ptext[] = postfix.getBytes("UTF8");byte ctext[] = cp.doFinal(ptext);String str = parseByte2HexStr(ctext);out.println(str); // 通過網絡將密文傳送到服務器// 將客戶端明文的Hash值傳送給服務器String x = postfix;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("MD5:"+result);out.println(result);//通過網絡將明文的Hash函數值傳送到服務器str = in.readLine();// 從網絡輸入流讀取結果System.out.println("從服務器接收到的結果為:" + str); // 輸出服務器返回的結果} catch (Exception e) {System.out.println(e);//輸出異常} finally {}}//將十六進制轉換成二進制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();}
}
運行結果:
實驗中遇到的問題
問題一:輸入表達算式時提示斷開連接
解決辦法:輸入表達式時一氣呵成,而不能像平常一樣對已輸入的括號內的內容進行修改
參考博客
https://www.cnblogs.com/zxy20175227/p/10923041.html
http://www.cnblogs.com/rocedu/p/6766748.html#SECDSA
結對伙伴及博客鏈接
20175227
轉載于:https://www.cnblogs.com/thz666/p/10945796.html
總結
以上是生活随笔為你收集整理的20175212童皓桢 实验五 网络编程与安全的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。