結對編程,完成網絡編程與安全相關內容html
- 設立一個棧,存放運算符,首先棧爲空; - 從左到右掃描中綴式,若遇到操做數,直接輸出,並輸出一個空格做爲兩個操做數的分隔符; - 若遇到運算符,則與棧頂比較,比棧頂級別高則進棧,不然退出棧頂元素並輸出,而後輸出一個空格做分隔符; - 若遇到左括號,進棧;若遇到右括號,則一直退棧輸出,直到退到左括號止。 - 當棧變成空時,輸出的結果即爲後綴表達式 後綴表達式求值僞代碼以下: - 設置一個操做數棧,開始棧爲空; - 從左到右遍歷後綴表達式,遇操做數,進棧; - 若遇運算符,則從棧中退出兩個元素,先退出的放到運算符的右邊,後退出的放到運算符左邊,運算後的結果再進棧,直到後綴表達式遍歷完畢。 - 重複以上步驟,直至後綴表達式結束,棧中最後一個數字就是表達式的值。
實驗代碼: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; else prec2 = 2; if (prec2 < prec1) { theStack.push(opTop); break; } else output = output + opTop; } } theStack.push(opThis); } public void getParen(char ch) { while (!theStack.isEmpty()) { char chx = theStack.pop(); if (chx == '(') break; else output = 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(); //若是是運算符,調用isOperator if (isOperator(token)) { //從棧中彈出操做數2 op2 = stack.pop(); //從棧中彈出操做數1 op1 = 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(); //若是是運算符,調用isOperator if (isOperator(token)) { //從棧中彈出操做數2 op2 = stack.pop(); //從棧中彈出操做數1 op1 = 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; } }
運行結果:
算法
任務二要求:express
1人負責客戶端,一人負責服務器編程
實驗過程數組
java.net.Socket:安全
ServerSocket是服務器套接字的一個實現。ServerSocket和Socket不一樣,服務器套接字的角色是,等待來自客戶端的鏈接請求。一旦服務器套接字得到了一個鏈接請求,它就會建立一個Socket實例,以處理和客戶端的通訊。服務器
Address網絡
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讀取信息,堵塞狀態 System.out.println("客戶收到服務器的回答:" + s); Thread.sleep(500);//在500毫秒數讓當前正在執行的線程休眠 } 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(); //堵塞狀態,除非有客戶呼叫 out = new DataOutputStream(socketOnServer.getOutputStream()); in = new DataInputStream(socketOnServer.getInputStream()); String s = in.readUTF(); // in讀取信息,堵塞狀態 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); } //} } }
運行結果:
app
任務三要求:
1人負責客戶端,一人負責服務器
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讀取信息,堵塞狀態 System.out.println("客戶收到服務器的回答:" + s); Thread.sleep(500);//在500毫秒數讓當前正在執行的線程休眠 } 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(); //堵塞狀態,除非有客戶呼叫 out = new DataOutputStream(socketOnServer.getOutputStream()); in = new DataInputStream(socketOnServer.getInputStream()); String s = in.readUTF(); // in讀取信息,堵塞狀態 // 獲取密文 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人負責客戶端,一人負責服務器
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 { // 一、建立客戶端Socket,指定服務器地址和端口 Socket socket=new Socket("192.168.56.1",2019); System.out.println("客戶端成功啓動,等待客戶端呼叫"); // 二、獲取輸出流,向服務器端發送信息 // 向本機的10001端口發出客戶請求 System.out.println("請輸入中綴表達式:"); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); // 由系統標準輸入設備構造BufferedReader對象 PrintWriter write = new PrintWriter(socket.getOutputStream()); // 由Socket對象獲得輸出流,並構造PrintWriter對象 //三、獲取輸入流,並讀取服務器端的響應信息 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( ); // 執行密鑰協定 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"則中止循環 write.println(Str); // 將從系統標準輸入讀入的字符串輸出到Server write.flush(); // 刷新輸出流,使Server立刻收到該字符串 System.out.println("加密後的信息:" + Str); // 在系統標準輸出上打印讀入的字符串 System.out.println("服務器發來的信息:" + in.readLine()); // 從Server讀入一字符串,並打印到標準輸出上 readline = br.readLine(); // 從系統標準輸入讀入一字符串 } // 繼續循環 //四、關閉資源 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);//建立服務器套接字 //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("客戶端發來的信息爲:"+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( ); // 執行密鑰協定 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( ); // 執行密鑰協定 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{ //三個靜態變量的定義從 // C:\j2sdk-1_4_0-doc\docs\guide\security\jce\JCERefGuide.html // 拷貝而來 // The 1024 bit Diffie-Hellman modulus values used by SKIP private 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 modulus private static final BigInteger skip1024Modulus = new BigInteger(1, skip1024ModulusBytes); // The base used with the SKIP 1024 bit modulus private 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人負責客戶端,一人負責服務器
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);// 建立服務器套接字 //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 n BigInteger 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(); // 從鍵盤讀入待發送的數據 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(); } }
運行結果:
問題一:輸入表達算式時提示斷開鏈接
解決辦法:輸入表達式時一鼓作氣,而不能像日常同樣對已輸入的括號內的內容進行修改
http://www.javashuo.com/article/p-hnfnmcqg-eo.html
http://www.cnblogs.com/rocedu/p/6766748.html#SECDSA