在本次實驗中我主要使用了書本第13章Java網絡編程以及Java密碼學的內容,基於TCP的信息傳輸使用socket進行實現,加密、解密、生成共享密鑰以及進行摘要驗證使用了Java中的JCA以及JCE。html
任務要求:算法
雖然該功能是後續步驟的基礎,但在之前的結對項目中已經實現過了,在這裏我就再也不多作介紹了,詳情請見博客結對編程項目-四則運算階段性總結
運行結果如圖:
編程
任務要求:數組
步驟:
一、建立數據輸入以及輸出流對象in和out用於創建鏈接後的數據傳輸。
二、客戶端建立套接字對象mysocket,並用構造方法Socket(String host,int port)給mysocket建立實體,而後讓mysocket調用getInputStream以及getoutputStream方法與服務器端創建鏈接。服務器端的步驟與客戶端相似,但在建立套接字時服務器端先建立一個ServerSocket對象,並用該對象調用accept方法來建立Socket類的實例。
三、客戶端與服務器端分別用對象out調用writeUTF方法來發送數據,對象in調用readUTF來接收數據。客戶端在輸入中綴表達式後轉化爲後綴表達式並經過out對象發送給服務器,服務器用in對象接收客戶端發送過來的後綴表達式進行計算,並將計算結果使用out對象發送給客戶端,客戶端使用in對象接收客戶端發來的數據並輸出。
運行結果以下:
安全
任務要求:服務器
該任務是在任務二的基礎上進行功能拓展,因而本任務中的網絡信息收發部分我就再也不介紹,我主要對加密及解密過程進行描述,而生成密鑰以及加密解密我都放在了Skey_kb
類中,並經過方法來實現功能的調用。
加解密步驟:網絡
一、生成密鑰併發
kg=KeyGenerator.getInstance("DESede");
kg.init(168);
k=kg.generateKey( );
FileOutputStream f=new FileOutputStream("key1.dat");ObjectOutputStream b=new ObjectOutputStream(f);b.writeObject(k);
二、改變密鑰保存方式
在解密時須要使用字節數組形式的密鑰,所以須要將密鑰以另外一種方式保存在文件中。less
三、加密socket
FileInputStream f=new FileInputStream("key1.dat");ObjectInputStream b=new ObjectInputStream(f);Key k=(Key)b.readObject( );
cp=Cipher.getInstance("DESede");
cp.init(Cipher.ENCRYPT_MODE, k);
String s="Hello World!";` byte ptext[]=s.getBytes("UTF8");
byte ctext[]=cp.doFinal(ptext);
FileOutputStream f2=new FileOutputStream("SEnc.dat"); f2.write(ctext);
四、解密
FileInputStream f=new FileInputStream("SEnc.dat"); int num=f.available(); byte[ ] ctext=new byte[num]; f.read(ctext);
須要注意的是,加密和解密的方法須要分別傳入明文以及密文的字符串,並將對應的密文以及明文做爲方法的輸出。在加密時須要將密文二進制字節數組轉化爲十六進制後再轉化爲字符串做爲發送數據,在解密時須要將密文轉化爲二進制後再進行解密。若是不進行數據轉化的話在進行密文傳輸時系統會報錯。
運行結果以下:
服務器端:
客戶端:
任務要求:
該過程是在任務三的基礎上進行的,我在這裏只介紹DH算法相關的內容。因爲生成公共密鑰前須要兩端交換公鑰,而兩端在兩個不一樣的文件夾中,因而我我在調用程序生成兩端各自的兩個密鑰後,使用套接字在客戶端與服務器之間進行了溝通,客戶端首先會給服務器發送已生成兩個密鑰鑰的信息,服務器在接收到該消息時也已經生成了兩個密鑰,在這時須要手動將二者的pub.dat文件進行交換,並在交換完成後在服務器端輸入準備好了的信息,併發送給客戶端,這樣一來就能夠正常進行加密及解密密鑰的生成了。須要注意的是因爲咱們使用的3DES是對外公佈的限制密鑰長度的版本,而DH算法生成的共享密鑰有128位,因此須要在生成加密密鑰後取得共享密鑰的前幾位,不然系統會顯示密鑰長度不合法。
運行結果以下:
任務要求:
在這部分中我增長了一次out以及in的調用用於兩端傳遞摘要,MD5建立摘要的過程以下所示:
一、生成MessageDigest對象MessageDigest
二、傳入須要計算的字符串m.update(x.getBytes("UTF8" ));
三、 計算消息摘要byte s[ ]=m.digest( );
四、將計算結果s轉換爲字符串
運行結果如圖:
服務器:
客戶端:
本次實驗是網絡編程以及Java密碼學的一個綜合,在實驗過程當中遇到的問題使我印象深入,SOLID原則十分重要,它不只能減小代碼的數量,更使得程序更加易讀,更易於修改,且不容易出錯。基於TCP的數據傳輸也不是爲所欲爲的,其對傳輸內容的格式也有要求,若是胡亂對傳輸內容進行格式轉換就極可能出錯。而咱們使用的JCE以及JCA都是限制功能的版本,在加密時只能使用很短的密鑰,從這也看出發達國家對技術的嚴格管制。