實驗搭檔王亦徐:http://www.cnblogs.com/1152wyx/p/5471524.htmlhtml
1.java
掌握Socket程序的編寫;算法
原理圖以下編程
插圖一:安全
信息(明文)採用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: