20145314鄭凱傑 《Java程序設計》實驗五 實驗報告

20145314鄭凱傑 《Java程序設計》實驗五 實驗報告

實驗搭檔王亦徐:http://www.cnblogs.com/1152wyx/p/5471524.htmlhtml

實驗要求

  1. 完成實驗、撰寫實驗報告,實驗報告以博客方式發表在博客園,注意實驗報告重點是運行結果,遇到的問題(工具查找,安裝,使用,程序的編輯,調試,運行等)、解決辦法(空洞的方法如「查網絡」、「問同窗」、「看書」等一概得0分)以及分析(從中能夠獲得什麼啓示,有什麼收穫,教訓等)。報告能夠參考範飛龍老師的指導
  2. 嚴禁抄襲,有該行爲者實驗成績歸零,並附加其餘懲罰措施。

實驗內容

1.java

掌握Socket程序的編寫;算法

  1. 掌握密碼技術的使用;
  2. 設計安全傳輸系統。

實驗知識點

  1. 用書上的TCP代碼,實現服務器與客戶端。
  2. 客戶端與服務器鏈接。
  3. 客戶端中輸入明文,利用DES算法加密,DES的祕鑰用RSA公鑰密碼中服務器的公鑰加密,計算明文的Hash函數值,一塊兒傳送給客戶端。
  4. 客戶端用RSA公鑰密碼中服務器的私鑰解密DES的,祕鑰,用祕鑰對密文進行解密,得出明文。計算求得明文的Hash函數值,檢查是否與傳送過來的一致,若是一致,則表示匹配成功。

原理圖以下編程

插圖一:安全

信息(明文)採用DES密鑰加密,使用RSA加密前面的DES密鑰信息,最終將混合信息進行傳遞。同時用hash函數將明文進行用做驗證。服務器

而接收方(本次實驗爲服務器)接收到信息後,用RSA解密DES密鑰信息,再用RSA解密獲取到的密鑰信息解密密文信息,最終就能夠獲得咱們要的明文。用hash函數對解出的明文進行驗證,與發送過來的hash值相等,驗證經過。稍後我將用"hello bitch"與個人搭檔王亦徐進行溝通,接下來請看實驗步驟:網絡

實驗步驟

本次實驗夥伴20145311王亦徐app

一、首先與王亦徐連上同一個WIFI,咱們採用手機熱點,穩定且相同的網絡是作好本次實驗的基礎。socket

二、接着在王亦徐的命令行中輸入ipconfig獲得服務器的ip地址。函數

王亦徐IP:

三、GET到王亦徐的IP地址以後,咱們就能夠創建一個Socket對象,用來鏈接特定服務器的指定端口,輸入的參數是剛剛獲取的ip地址和雙方默認的同一端口。咱們端口號是9090。

所以,咱們的Socket實例爲:Socket socket = new Socket("172.26.168.2", 9090);

四、接着利用BufferedReader對象得到從服務器傳來的網絡輸入流,用PrintWriter對象得到從客戶端向服務器輸出數據的網絡輸出流,用BufferedReader對象建立鍵盤輸入流,以便客戶端從鍵盤上輸入信息。這部分直接能夠用到老師給咱們的代碼,我是客戶端,因此代碼以下:

package com.company;

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 Main
{
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("172.26.168.2", 9090);//這裏輸入的是服務器的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;
}
}

五、獲得了明文就能夠將客戶端明文的Hash值傳送給服務器,而後會收到來自服務器的返回數據

六、實驗就成功了:

成功 王亦徐:

成功 鄭凱傑:

實驗中的問題和解決過程

一、第一個遇到的問題是WIFI問題

若是雙方鏈接CMCC-EDU的話,成功率是比較低的。

就會出現鏈接超時的問題:

失敗:

這是因爲有些端口已被佔用,這時候咱們能夠用如下三種方法解決這個問題:

①能夠用老師上傳給咱們的XAMPP軟件,查看已被使用的端口十分方便。

②能夠在命令行中輸入netstat -na就能看到當前的端口號的佔用狀況。

③鏈接私人WIFI,即手機熱點,成功率暴漲。

二、文件缺失問題

相信你們第一次作都會出現以下狀況:

失敗 缺失文件:

咱們只要將老師給咱們的文件拷入JDK目錄下便可:

找不到文件解決:

實驗代碼託管截圖

代碼:

其餘(感悟、思考等,可選)

最後一次JAVA實驗,此次的實驗實用性比較強,並且結合了本週學習內容——網絡編程。實驗與知識契合度高的話作起來也比較快。本次實驗找到了搭檔王亦徐,配合起來也比較快,一對一進行實驗,對於處理和分析問題,效率大大提升。兩我的也對同一個問題有着不一樣的解決方法,因此今天的解決方法比較多。相信下週開始作項目以後會取得更好的效果!

PSP

PSP:

相關文章
相關標籤/搜索