實驗內容:
兩人一組結對編程:html
實驗內容:
結對編程:1人負責客戶端,一人負責服務器java
上傳測試結果截圖和碼雲連接
在本次實驗中我負責服務器,將從客戶端傳過來的後綴表達式進行計算而後傳給客戶端。
經過socketOnServer = serverForClient.accept()
接受客戶端傳過來的字符串數據,而後經過建立服務器的輸入輸出流,把輸入輸出流指向服務器out=new DataOutputStream(socketOnServer.getOutputStream());
,in=new DataInputStream(socketOnServer.getInputStream());
。in.readUTF()
來讀取客戶端傳來的數據,out.writeUTF(m+"");
把數據寫入客戶端。git
代碼連接算法
上傳測試結果截圖和碼雲連接編程
key1.dat
文件,並打印出文件的編碼:import java.io.*; import java.security.*; public class Skey_kb{ public static void main(String args[]) throws Exception{ FileInputStream f=new FileInputStream("key1.dat"); ObjectInputStream b=new ObjectInputStream(f); Key k=(Key)b.readObject( ); byte[ ] kb=k.getEncoded( ); FileOutputStream f2=new FileOutputStream("keykb1.dat"); f2.write(kb); // 打印密鑰編碼中的內容 for(int i=0;i<kb.length;i++){ System.out.print(kb[i]+","); } } }
byte
寫入byte
數組a中,並用數組a做爲祕鑰來進行加密代碼連接數組
建立DH公鑰和私鑰:安全
key_DH
代碼:public class Key_DH{ private static final byte skip1024ModulusBytes[] = { (byte)0xF4, (byte)0x88, (byte)0xFD, (byte)0x58, (byte)0x4E, (byte)0x49, (byte)0xDB, (byte)0xCD, (byte)0x20, (byte)0xB4, (byte)0x9D, (byte)0xE4, (byte)0x91, (byte)0x07, (byte)0x36, (byte)0x6B, (byte)0x33, (byte)0x6C, (byte)0x38, (byte)0x0D, (byte)0x45, (byte)0x1D, (byte)0x0F, (byte)0x7C, (byte)0x88, (byte)0xB3, (byte)0x1C, (byte)0x7C, (byte)0x5B, (byte)0x2D, (byte)0x8E, (byte)0xF6, (byte)0xF3, (byte)0xC9, (byte)0x23, (byte)0xC0, (byte)0x43, (byte)0xF0, (byte)0xA5, (byte)0x5B, (byte)0x18, (byte)0x8D, (byte)0x8E, (byte)0xBB, (byte)0x55, (byte)0x8C, (byte)0xB8, (byte)0x5D, (byte)0x38, (byte)0xD3, (byte)0x34, (byte)0xFD, (byte)0x7C, (byte)0x17, (byte)0x57, (byte)0x43, (byte)0xA3, (byte)0x1D, (byte)0x18, (byte)0x6C, (byte)0xDE, (byte)0x33, (byte)0x21, (byte)0x2C, (byte)0xB5, (byte)0x2A, (byte)0xFF, (byte)0x3C, (byte)0xE1, (byte)0xB1, (byte)0x29, (byte)0x40, (byte)0x18, (byte)0x11, (byte)0x8D, (byte)0x7C, (byte)0x84, (byte)0xA7, (byte)0x0A, (byte)0x72, (byte)0xD6, (byte)0x86, (byte)0xC4, (byte)0x03, (byte)0x19, (byte)0xC8, (byte)0x07, (byte)0x29, (byte)0x7A, (byte)0xCA, (byte)0x95, (byte)0x0C, (byte)0xD9, (byte)0x96, (byte)0x9F, (byte)0xAB, (byte)0xD0, (byte)0x0A, (byte)0x50, (byte)0x9B, (byte)0x02, (byte)0x46, (byte)0xD3, (byte)0x08, (byte)0x3D, (byte)0x66, (byte)0xA4, (byte)0x5D, (byte)0x41, (byte)0x9F, (byte)0x9C, (byte)0x7C, (byte)0xBD, (byte)0x89, (byte)0x4B, (byte)0x22, (byte)0x19, (byte)0x26, (byte)0xBA, (byte)0xAB, (byte)0xA2, (byte)0x5E, (byte)0xC3, (byte)0x55, (byte)0xE9, (byte)0x2F, (byte)0x78, (byte)0xC7 }; // The SKIP 1024 bit modulus private static final BigInteger skip1024Modulus = new BigInteger(1, skip1024ModulusBytes); // The base used with the SKIP 1024 bit modulus private static final BigInteger skip1024Base = BigInteger.valueOf(2); public static void main(String args[ ]) throws Exception{ DHParameterSpec DHP= new DHParameterSpec(skip1024Modulus,skip1024Base); KeyPairGenerator kpg= KeyPairGenerator.getInstance("DH"); kpg.initialize(DHP); KeyPair kp=kpg.genKeyPair(); PublicKey pbk=kp.getPublic(); PrivateKey prk=kp.getPrivate(); // 保存公鑰 FileOutputStream f1=new FileOutputStream(args[0]); ObjectOutputStream b1=new ObjectOutputStream(f1); b1.writeObject(pbk); // 保存私鑰 FileOutputStream f2=new FileOutputStream(args[1]); ObjectOutputStream b2=new ObjectOutputStream(f2); b2.writeObject(prk); } }
KeyAgree
代碼:import java.security.PublicKey; import java.security.PrivateKey; import java.io.*; import javax.crypto.KeyAgreement; import javax.crypto.spec.*; public class KeyAgree{ public static void main(String args[ ]) throws Exception{ // 讀取對方的DH公鑰 FileInputStream f1=new FileInputStream(args[0]); ObjectInputStream b1=new ObjectInputStream(f1); PublicKey pbk=(PublicKey)b1.readObject( ); //讀取本身的DH私鑰 FileInputStream f2=new FileInputStream(args[1]); ObjectInputStream b2=new ObjectInputStream(f2); PrivateKey prk=(PrivateKey)b2.readObject( ); // 執行密鑰協定 KeyAgreement ka=KeyAgreement.getInstance("DH"); ka.init(prk); ka.doPhase(pbk,true); //生成共享信息 byte[ ] sb=ka.generateSecret(); for(int i=0;i<sb.length;i++){ System.out.println(sb[i]+","); } SecretKeySpec k=new SecretKeySpec(sb,"AES"); } }
在Windows命令行中輸入:java Key_DH Apub.dat Apri.dat
和 java Key_DH Bpub.dat Bpri.dat
,產生A的公鑰Apub.dat
和私鑰Apri.dat
,B的公鑰Bpub.dat
和私鑰Bpri.dat
,A,B各自存放對方私鑰,經過信道傳輸各自公鑰。服務器
A用Apub.dat
和Bpri.dat
產生共享密鑰,B一樣使用Bpub.dat
,Bpri.dat
生成共享密鑰。加解密就用共享密鑰。且二者生成的共享密鑰是相同的,比對Ckey.dat
和Dkey.dat
打印的編碼相同。網絡
ckey.dat
寫入字節數組中:Ckey.dat
進行解密,客戶端用共享祕鑰Dkey.dat
加密:代碼連接socket
上傳測試結果截圖和碼雲連接
MD5即Message-Digest Algorithm 5(信息-摘要算法5),用於確保信息傳輸完整一致。
在windo命令行中輸入:java DigestCalc 20165235qy ying
來進行查看消息摘要。
import java.security.*; public class DigestPass{ static String md5(String str) throws Exception{ MessageDigest m=MessageDigest.getInstance("MD5"); m.update(str.getBytes("UTF8")); byte s[ ]=m.digest( ); String result=""; for (int i=0; i<s.length; i++){ result+=Integer.toHexString((0x000000ff & s[i]) | 0xffffff00).substring(6); } return result; } }
經過本次實驗,對java密碼學和java網絡編程有了深度的學習。
步驟 | 耗時 | 百分比 |
---|---|---|
需求分析 | 20min | 8% |
設計 | 60min | 25% |
代碼實現 | 120min | 50% |
測試 | 10min | 4% |
分析總結 | 30min | 13% |