20165235 實驗五 網絡編程與安全

20165235 實驗五 網絡編程與安全


實驗課程:JAVA編程設計

實驗名稱:網絡編程與安全

姓名:祁瑛

學號:20165235

實驗時間:2018.05.27

指導老師:婁家鵬


實驗一

實驗內容:
兩人一組結對編程:html

  • 參考http://www.cnblogs.com/rocedu/p/6766748.html#SECDSA
  • 結對實現中綴表達式轉後綴表達式的功能 MyBC.java
  • 結對實現從上面功能中獲取的表達式中實現後綴表達式求值的功能,調用MyDC.java
  • 上傳測試代碼運行結果截圖和碼雲連接
    根據僞代碼編寫程序:
  • 設立一個棧,存放運算符,首先棧爲空;
  • 從左到右掃描中綴式,若遇到操做數,直接輸出,並輸出一個空格做爲兩個操做數的分隔符;
  • 若遇到運算符,則與棧頂比較,比棧頂級別高則進棧,不然退出棧頂元素並輸出,而後輸出一個空格做分隔符;
  • 若遇到左括號,進棧;若遇到右括號,則一直退棧輸出,直到退到左括號止。
  • 當棧變成空時,輸出的結果即爲後綴表達式。
  • 代碼連接

實驗二

實驗內容:
結對編程:1人負責客戶端,一人負責服務器java

  • 注意責任歸宿,要會經過測試證實本身沒有問題
  • 基於Java Socket實現客戶端/服務器功能,傳輸方式用TCP
  • 客戶端讓用戶輸入中綴表達式,而後把中綴表達式調用MyBC.java的功能轉化爲後綴表達式,把後綴表達式經過網絡發送給服務器
  • 服務器接收到後綴表達式,調用MyDC.java的功能計算後綴表達式的值,把結果發送給客戶端
  • 客戶端顯示服務器發送過來的結果
  • 上傳測試結果截圖和碼雲連接
    在本次實驗中我負責服務器,將從客戶端傳過來的後綴表達式進行計算而後傳給客戶端。
    經過socketOnServer = serverForClient.accept()接受客戶端傳過來的字符串數據,而後經過建立服務器的輸入輸出流,把輸入輸出流指向服務器out=new DataOutputStream(socketOnServer.getOutputStream());,in=new DataInputStream(socketOnServer.getInputStream());in.readUTF()來讀取客戶端傳來的數據,out.writeUTF(m+"");把數據寫入客戶端。git

     下圖爲實驗截圖:

  • 代碼連接算法

    實驗三

    實驗內容
    結對編程:1人負責客戶端,一人負責服務器
  • 注意責任歸宿,要會經過測試證實本身沒有問題
  • 基於Java Socket實現客戶端/服務器功能,傳輸方式用TCP
  • 客戶端讓用戶輸入中綴表達式,而後把中綴表達式調用MyBC.java的功能轉化爲後綴表達式,把後綴表達式經過網絡發送給服務器
  • 服務器接收到後綴表達式,調用MyDC.java的功能計算後綴表達式的值,把結果發送給客戶端
  • 客戶端顯示服務器發送過來的結果
  • 上傳測試結果截圖和碼雲連接編程

     首先經過老師給出的代碼生成祕鑰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做爲祕鑰來進行加密

 此爲程序運行截圖:

  • 代碼連接數組

    實驗四

    實驗內容
    密鑰分發結對編程:1人負責客戶端,一人負責服務器
  • 注意責任歸宿,要會經過測試證實本身沒有問題
  • 基於Java Socket實現客戶端/服務器功能,傳輸方式用TCP
  • 客戶端讓用戶輸入中綴表達式,而後把中綴表達式調用MyBC.java的功能轉化爲後綴表達式,把後綴表達式用3DES或AES算法加密經過網絡把密文發送給服務器
  • 客戶端和服務器用DH算法進行3DES或AES算法的密鑰交換
  • 服務器接收到後綴表達式表達式後,進行解密,而後調用MyDC.java的功能計算後綴表達式的值,把結果發送給客戶端
  • 客戶端顯示服務器發送過來的結果
  • 上傳測試結果截圖和碼雲連接
    執行密鑰協定的標準算法是DH算法(Diffie-Hellman算法),分爲如下兩步:
    建立DH公鑰和私鑰;
    建立共享密鑰。
  • 建立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.datjava Key_DH Bpub.dat Bpri.dat,產生A的公鑰Apub.dat和私鑰Apri.dat,B的公鑰Bpub.dat和私鑰Bpri.dat,A,B各自存放對方私鑰,經過信道傳輸各自公鑰。服務器


A用Apub.datBpri.dat產生共享密鑰,B一樣使用Bpub.datBpri.dat生成共享密鑰。加解密就用共享密鑰。且二者生成的共享密鑰是相同的,比對Ckey.datDkey.dat打印的編碼相同。網絡

 此爲服務器用B公鑰和A私鑰生成共享密鑰,並將生成的共享密鑰ckey.dat寫入字節數組中:

 此爲客戶端用A公鑰和B私鑰生成共享密鑰,並將生成的共享密鑰寫入字節數組中:

 下爲服務器運行截圖,服務器用共享密鑰Ckey.dat進行解密,客戶端用共享祕鑰Dkey.dat加密:

  • 代碼連接socket

    實驗五

    實驗內容
    完整性校驗結對編程:1人負責客戶端,一人負責服務器
  • 注意責任歸宿,要會經過測試證實本身沒有問題
  • 基於Java Socket實現客戶端/服務器功能,傳輸方式用TCP
  • 客戶端讓用戶輸入中綴表達式,而後把中綴表達式調用MyBC.java的功能轉化爲後綴表達式,把後綴表達式用3DES或AES算法加密經過網絡把密文和明文的MD5値發送給服務器
  • 客戶端和服務器用DH算法進行3DES或AES算法的密鑰交換
  • 服務器接收到後綴表達式表達式後,進行解密,解密後計算明文的MD5值,和客戶端傳來的MD5進行比較,一致則調用MyDC.java的功能計算後綴表達式的值,把結果發送給客戶端
  • 客戶端顯示服務器發送過來的結果
  • 上傳測試結果截圖和碼雲連接
    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%
相關文章
相關標籤/搜索