實驗內容
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%