20145326 《Java程序設計》實驗五——Java網絡編程及安全實驗報告


實驗內容

1.掌握Socket程序的編寫;

2.掌握密碼技術的使用;

3.設計安全傳輸系統。

實驗步驟

我和20145211黃志遠http://www.cnblogs.com/nostalgia-/組隊編程,我設計Client部分。

  • 確定服務器端IP地址和端口

    用設計服務器的電腦打開cmd命令行,在其中輸入ipconfig查詢服務器的IPv4地址並讓負責客戶端的用戶記錄下來,創立一個端口號且服務器和客戶端一致(最好不要為8080、8030這些常見的)。

  • Skey_RSA_priv.dat與Skey_RSA_pub.dat拷貝至與src同級的文件夾內,這樣運行后才不會顯示錯誤“系統找不到指定文件”。
  • 編寫代碼

    1.建立一個Socket對象,用來建立一個端口號與客戶端相連,獲得網絡輸入流與輸出流對象的引用。

    2.使用服務器端RSA的私鑰對DES的密鑰進行解密,對秘鑰進行解密之后使用DES對密文進行解密。

    3.計算解密后的hash值來確定解密是否正確。

    注:加密算法、秘鑰、Hash函數計算過程均利用的老師提供的代碼

    客戶端代碼如下:

  • package exp05;

    /**
    * Created by Administrator on 2016/5/6.
    */
    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.*;
    /**
    * Created by Think on 2016/5/6.
    */
    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[] ptext2 = k.getEncoded();

    // 創建連接特定服務器的指定端口的Socket對象
    Socket socket = new Socket("192.168.43.125", 12335);//這里輸入的是服務器的ip地址和端口號,端口號要注意和服務器保持一致。

    // 獲得從服務器端來的網絡輸入流
    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); // 通過網絡將加密后的秘鑰傳送到服務器

    //用DES加密明文得到密文
    System.out.print("請輸入待發送的數據:");
    String s = stdin.readLine(); // 從鍵盤讀入待發送的數據
    Cipher cp = Cipher.getInstance("DESede");
    cp.init(Cipher.ENCRYPT_MODE, k);
    byte ptext[] = s.getBytes("UTF8");
    byte ctext[] = cp.doFinal(ptext);
    String str = parseByte2HexStr(ctext);
    out.println(str); // 通過網絡將密文傳送到服務器

    // 將客戶端明文的Hash值傳送給服務器
    String x = s;
    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(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();
    }

    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;
    }
    }
  • 匹配連接

    1.運行服務器端代碼;

    2.顯示“服務器已經啟動后”運行客戶端代碼;

    3.顯示“已經建立連接”就證明雙方已經連接好了;

    4.客戶端輸入要傳輸的信息;

    5.服務器端顯示從客戶端接受到的信息;

    6.雙方匹配成功,並在客戶端顯示“匹配成功”的消息。

  • 我們將端口設置為:12333. 從命令行中得知服務器的IP為:192.168.43.125
  • 服務器方:
  • 然后服務器方點擊“run”,客戶端再“run”,這樣就建立了連接。

      客戶端輸入發送的數據:

  • 服務器收到數據:
  • 實驗中的問題和解決過程

    • 問題1:運行后顯示錯誤“系統找不到指定文件”。
    • 解決:Skey_RSA_priv.dat拷貝至與src同級的文件夾內。
    • 問題2:服務器啟動后客戶端顯示錯誤java.net.SocketException: Connection reset(連接重置)
    • 解決:沒有關閉上次運行的窗口,端口號被占用,關閉上次運行的窗口后就可以成功了。
    • 問題3:服務器啟動后客戶端顯示錯誤`java.net.ConnectException: Connection timed out: connect(連接超時).
    • 解決:我們推斷可能是網絡連接有問題。我們最初同時使用edu的wifi,結果為連接超時;然后,我們連接同一台手機散發的熱點,結果仍然為連接超時;最后,我用服務器端的電腦給客戶端散發WiFi,結果就成功了,很神奇。

    • 實驗代碼托管截圖

    • 客戶端代碼:
      • 服務器代碼:
  • PSP(Personal Software Process)時間

  • 步驟 耗時 百分比
    需求分析 10min 12.5%
    設計 20min 25%
    代碼實現 20min 25%
    測試 20min 25%
    分析總結 10min 12.5%


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM