日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

20165310 Java实验五《网络编程与安全》

發布時間:2024/9/5 java 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 20165310 Java实验五《网络编程与安全》 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

20165310 Java實驗五《網絡編程與安全》

任務一

  • 題目:①編寫MyBC.java實現中綴表達式轉后綴表達式的功能;②編寫MyDC.java實現從上面功能中獲取的表達式中實現后綴表達式求值的功能

  • 中綴轉后綴的算法可描述為:

    • 設置一個運算符棧,設置一個后綴表達式字符串;
    • 從左到右依次對中綴表達式中的每個字符ch分別進行以下處理,直至表達式結束:
    • 若ch是左括號‘(’,將其入棧;
    • 若ch是數字,將其后連續若干數字添加到后綴表達式字符串之后,并添加空格作為分隔符;
    • 若ch是運算符,先將棧頂若干優先級高于ch的運算符出棧,添加到后綴表達式字符串之后,再將ch入棧。當‘(’運算符在棧中時,它的優先級最低。
    • 若ch是‘)’,則若干運算符全部出棧,直到出棧的是左括號,一對括號匹配。
    • 若表達式結束,將棧中運算符全部出棧,添加到后綴表達式字符串之后。
  • 后綴表達式求值的算法可描述為(參考:婁老師的博客):

    • 設置一個操作數棧,從左向右依次對后綴表達式字符串中的每個字符ch進行處理;
    • 若ch是數字,先將其后連續若干數字轉化為整數,再將該整數入棧;
    • 若ch是運算符,出棧兩個值進行運算,運算結果再入棧;
    • 重復以上步驟,直至后綴表達式結束,棧中最后一個數字就是所求表達式的值。
  • 在我之前的實驗一中有更為詳細的代碼與解釋:《20165310_JavaExp1_Java開發環境的熟悉》

  • 添加的測試代碼:

    public class NewMyDCTester {public static void main(String [] args) {String expression;int result;try{Scanner in = new Scanner(System.in);NewMyDC evaluator = new NewMyDC();System.out.println ("Enter a valid postfix expression: ");expression = in.nextLine();String postfix = MyBC.toPostfix(expression);System.out.println ("The postfix expression is :" + postfix);result = evaluator.value (postfix);System.out.println ("That expression equals :" + result);}catch (Exception IOException){System.out.println("Input exception reported");}} }

    ?

  • 實驗運行結果:

任務二

  • 題目:①結對編程:一人負責客戶端,另一人負責服務器;②注意責任歸宿,要會通過測試證明自己沒有問題;③基于Java Socket實現客戶端/服務器功能,傳輸方式用TCP;④客戶端讓用戶輸入中綴表達式,然后把中綴表達式調用MyBC.java的功能轉化為后綴表達式,把后綴表達式通過網絡發送給服務器;⑤服務器接收到后綴表達式,調用MyDC.java的功能計算后綴表達式的值,把結果發送給客戶端;⑥客戶端顯示服務器發送過來的結果

  • 我的任務是客戶端,代碼如下:

    import java.io.DataInputStream; import java.io.DataOutputStream; import java.net.Socket; import java.util.Scanner;public class Client {public static void main(String[] args) {String str;System.out.println("請輸入要計算的中綴式:");Scanner scanner=new Scanner(System.in);str=scanner.nextLine();Socket myClientSocket;DataInputStream in=null;DataOutputStream out=null;ChangeExpress chedExp=new ChangeExpress();chedExp.setOriginalExpression(str);chedExp.changedWay();System.out.println("發送給服務器的后綴式為:"+chedExp.changedExpression);try {myClientSocket = new Socket("10.1.1.165",2010);System.out.println("客戶端已啟動");in=new DataInputStream(myClientSocket.getInputStream());out=new DataOutputStream(myClientSocket.getOutputStream());out.writeUTF(chedExp.changedExpression);String answer=in.readUTF();System.out.println("服務器端計算結果是:"+answer);Thread.sleep(500);}catch (Exception e){System.out.println("服務器已斷開"+e);}} }
  • java.net.Socket

    • 套接字是一個網絡連接的端點。在java中,使用java.net.Socket對象來表示一個套接字。要創建一個套接字,可以使用Socket的構造方法,如:public Socket(java.lang.String host, int port)。其中,host是遠程機器名或IP地址,port是遠程應用程序的端口號。上述代碼中,IP地址為:"10.1.1.165",端口號為:2010。
    • 成功創建Socket類的一個實例后,就可以使用它發送或接收字節流。發送字節流,必須先調用Socket類的getOutputStream方法來獲取一個java.io.OutputStream對象。接收字節流,可以調用Socket類的getInputStream方法,它返回一個java.io.InputStream。
  • 運行結果

任務三

  • 題目:①客戶端讓用戶輸入中綴表達式,然后把中綴表達式調用MyBC.java的功能轉化為后綴表達式,把后綴表達式用3DES或AES算法加密后通過網絡把密文發送給服務器;②服務器接收到后綴表達式表達式后,進行解密(和客戶端協商密鑰,可以用數組保存),然后調用MyDC.java的功能計算后綴表達式的值,把結果發送給客戶端。其他要求同任務二。

  • 客戶端RSA加密代碼

    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 srgs[]) throws Exception {try {KeyGenerator kg = KeyGenerator.getInstance("DESede");kg.init(168);SecretKey k = kg.generateKey();byte[] ptext = k.getEncoded();Socket socket = new Socket("192.168.43.109", 2010);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(ptext);BigInteger c = m.modPow(e, n);String cs = c.toString();out.println(cs); // 通過網絡將加密后的秘鑰傳送到服務器System.out.println("請輸入中綴式:");//用DES加密明文得到密文String s = stdin.readLine(); // 從鍵盤讀入待發送的數據String plain = MyBC.changeWay(s);Cipher cp = Cipher.getInstance("DESede");cp.init(Cipher.ENCRYPT_MODE, k);byte ptext1[] = plain.getBytes("UTF8");byte ctext[] = cp.doFinal(ptext1);String str = parseByte2HexStr(ctext);out.println(str); // 通過網絡將密文傳送到服務器System.out.println("從服務器接收到的結果為:" + str); // 輸出結果} catch (Exception e) {System.out.println("服務器斷開連接"+e);//輸出異常}}}

    ?

  • 實驗結果

任務四

  • 題目:任務三基礎上增加客戶端和服務器用DH算法進行3DES或AES算法的密鑰交換。
  • 創建DH公鑰和私鑰:
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 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(args[0]);ObjectOutputStream b1=new ObjectOutputStream(f1);b1.writeObject(pbk);// 保存私鑰FileOutputStream f2=new FileOutputStream(args[1]);ObjectOutputStream b2=new ObjectOutputStream(f2);b2.writeObject(prk);} }
  • 創建共享密鑰

DH算法中,A可以用自己的密鑰和B的公鑰按照一定方法生成一個密鑰,B也可以用自己的密鑰和A的公鑰按照一定方法生成一個密鑰,由于一些數學規律,這兩個密鑰完全相同。這樣,A和B間就有了一個共同的密鑰可以用于各種加密。本實例介紹Java中在上一小節的基礎上如何利用DH公鑰和私鑰各自創建共享密鑰。

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(args[0]);ObjectInputStream b1=new ObjectInputStream(f1);PublicKey pbk=(PublicKey)b1.readObject( ); //讀取自己的DH私鑰FileInputStream f2=new FileInputStream(args[1]);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");} }
  • 運行結果

任務五

  • 題目:任務四的基礎上,在服務器接收到后綴表達式表達式后,進行解密,解密后計算明文的MD5值,和客戶端傳來的MD5進行比較,一致則調用MyDC.java的功能計算后綴表達式的值,把結果發送給客戶端。

  • MD5算法

    使用Java計算指定字符串的消息摘要。
    java.security包中的MessageDigest類提供了計算消息摘要的方法,

    最后的實現代碼:

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 srgs[]) throws Exception {try {KeyGenerator kg = KeyGenerator.getInstance("DESede");kg.init(168);SecretKey k = kg.generateKey();byte[] ptext = k.getEncoded();Socket socket = new Socket("192.168.43.109", 2010);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(ptext);BigInteger c = m.modPow(e, n);String cs = c.toString();out.println(cs); // 傳送秘鑰到服務器System.out.println("請輸入中綴式:");//用DES加密明文得到密文String s = stdin.readLine(); // 從鍵盤讀入待發送的數據String plain = MyBC.changeWay(s);Cipher cp = Cipher.getInstance("DESede");cp.init(Cipher.ENCRYPT_MODE, k);byte ptext1[] = plain.getBytes("UTF8");byte ctext[] = cp.doFinal(ptext1);String str = parseByte2HexStr(ctext);out.println(str); // 傳送密文傳送到服務器String str = plain;MessageDigest m2 = MessageDigest.getInstance("MD5");m2.update(str.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(result);out.println(result);//傳送HASH到服務器str = in.readLine();// 網絡輸入流讀取結果System.out.println("從服務器接收到的結果為:" + str); // 輸出服務器返回的結果} catch (Exception e) {System.out.println("服務器斷開連接"+e);}}//將十六進制轉換成二進制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();} }
  • 運行結果

問題總結

  • 在端口和IP正確的情況下客戶端與服務器無法連接:
    • 是由于沒有處于同一網絡中,必須在同一網絡中可以連接。
  • 服務器接受不到客戶端發送的消息
    • 由于阻塞問題,可用Thread類解決,或者可以改變輸入輸出流,在任務二中,我直接修改引用了書上例子三的代碼就可以完成,但是在任務三中由于阻塞的原因無法進行通信,參考狄維佳學姐的博客,將DataOutputStream更改為PrintWriter,將DataInputStream更改為BufferReader,解決了阻塞問題。

轉載于:https://www.cnblogs.com/atbaoi/p/9101025.html

總結

以上是生活随笔為你收集整理的20165310 Java实验五《网络编程与安全》的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。