1. 程式人生 > 其它 >網路安全技術與應用實驗——SSL驗證分析 & 基於DTLS的安全伺服器設計

網路安全技術與應用實驗——SSL驗證分析 & 基於DTLS的安全伺服器設計

1. SSL驗證分析

實驗目的:通過實驗,掌握SSL的基本原理,掌握掃描器的基本原理和基本工具Wireshark的使用。

實驗內容:使用Wireshark工具分析TCP連線中主機和伺服器之間傳輸SSL資料包。

本實驗中能夠利用wireshark抓包並分析捕獲的資料包

ubuntu20 python3.8 python3-dtls

安裝 wireshark

sudo add-apt-repository universe
sudo apt install wireshark

安裝 python3-dtls

pip install python3-dtls

執行

sudo wireshark

就會直接跳出

開啟淘寶東點點西點點,然後 wireshark 裡面我選擇了有限,然後雙擊 any 那個,也可以選擇 ens33

過濾器裡填入ssl,Protocol 找到 TCP 就行了,抓包任務完成

儲存截圖

2.基於DTLS的安全伺服器設計傳輸層和應用層

實驗目的:通過實驗,掌握DTLS的基本原理,掌握python3-dtls庫的基本使用。

實驗內容:

(1)利用 DTLS 庫編寫客戶端和伺服器程式,服務端開啟監聽,提供資料傳輸、檔案傳輸功能;

(2) 客戶端對服務端進行證書認證(單向認證);

(3) 利用相關工具(如 Wireshark)驗證 DTLS 通訊結果;

首先方便程式設計,安裝spyder

sudo apt install spyder

出現如下錯誤,考慮換源

先備份源

sudo cp -a /etc/apt/sources.list /etc/apt/sources.list.bak

更換源,自己編輯,編輯/etc/apt/sources.list檔案, 在檔案最前面新增以下條目(操作前請做好相應備份):

sudo gedit /etc/apt/sources.list

連結:https://blog.csdn.net/xiangxianghehe/article/details/105688062

#阿里源
deb http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse

然後執行命令:

sudo apt-get update
sudo apt-get upgrade

然後再安裝就成功了

在Ubuntu中 我們使用sudo ufw disable命令來關閉防火牆。執行該命令之後 我們使用sudo ufw status命令來檢視當前防火牆的狀態 如果是inactive 說明我們的防火牆已經關閉掉了。

金鑰生成 https://blog.csdn.net/lwz15071387627/article/details/88103997

原文連結:https://blog.csdn.net/qq_40909772/article/details/88901202

原文連結:https://blog.csdn.net/zhongbing1234/article/details/84797391

https://www.jianshu.com/p/1de38a3f50f3

檢視程式碼
cys@ubuntu:~/NetworkSecurity/EXP1/miyao$ openssl genrsa  -out server.key 2048
Generating RSA private key, 2048 bit long modulus (2 primes)
............................................+++++
.....................................................................................................................+++++
e is 65537 (0x010001)
cys@ubuntu:~/NetworkSecurity/EXP1/miyao$ openssl req -new -key server.key -out server.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:hunan  
Locality Name (eg, city) []:changsha
Organization Name (eg, company) [Internet Widgits Pty Ltd]:nudt
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:127.0.0.1
Email Address []:[email protected]
​
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:123456
An optional company name []:
cys@ubuntu:~/NetworkSecurity/EXP1/miyao$ openssl req -new -key server.key -out server.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:hunan
Locality Name (eg, city) []:changsha
Organization Name (eg, company) [Internet Widgits Pty Ltd]:nudt
Organizational Unit Name (eg, section) []:cs
Common Name (e.g. server FQDN or YOUR name) []:127.0.0.1
Email Address []:[email protected]
​
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:654321
An optional company name []:
cys@ubuntu:~/NetworkSecurity/EXP1/miyao$ openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
Signature ok
subject=C = CN, ST = hunan, L = changsha, O = nudt, OU = cs, CN = 127.0.0.1, emailAddress = [email protected]
Getting Private key
cys@ubuntu:~/NetworkSecurity/EXP1/miyao$ cat server.crt server.key > localhost.pem
cys@ubuntu:~/NetworkSecurity/EXP1/miyao$

最終版本

檢視程式碼
cys@ubuntu:~/NetworkSecurity/EXP1/certs$ openssl genrsa  -out key.pem 2048 
Generating RSA private key, 2048 bit long modulus (2 primes)
...............+++++
...................................+++++
e is 65537 (0x010001)
cys@ubuntu:~/NetworkSecurity/EXP1/certs$ openssl req -new -key key.pem -out cert.csr 
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:ch
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:127.0.0.1
Email Address []:
​
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:123456
An optional company name []:
cys@ubuntu:~/NetworkSecurity/EXP1/certs$ openssl x509 -req -days 365 -in cert.csr -signkey key.pem -out cert.pem
Signature ok
subject=C = ch, ST = Some-State, O = Internet Widgits Pty Ltd, CN = 127.0.0.1
Getting Private key
cys@ubuntu:~/NetworkSecurity/EXP1/certs$ cat cert.pem key.pem > keycert.pem

伺服器程式碼

scn = SSLConnection(
        sck,
        keyfile=path.join(cert_path,"keycert.pem"),
        certfile=path.join(cert_path,"keycert.pem"),
        server_side=True,
        ca_certs=path.join(cert_path,"cert.pem"),
        do_handshake_on_connect=False
        )

採用老師 3.31 上午的程式碼和檔案

server.py的程式碼如下:

檢視程式碼
import socket
import subprocess
from os import path
from logging import basicConfig, DEBUG
#basicConfig(level=DEBUG)  # set now for dtls import code
from dtls.sslconnection import SSLConnection
from dtls.err import SSLError, SSL_ERROR_WANT_READ, SSL_ERROR_ZERO_RETURN
​
blocksize = 1024
​
#def main():
current_path = path.abspath(path.dirname(__file__))
cert_path = path.join(current_path, "certs")
sck = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sck.bind(("127.0.0.1", 28000))
sck.settimeout(30)
​
print("ok1")
scn = SSLConnection(
    sck,
    keyfile=path.join(cert_path, "keycert_ec.pem"),
    certfile=path.join(cert_path, "keycert_ec.pem"),
    server_side=True,
    ca_certs=path.join(cert_path, "ca-cert_ec.pem"),
    do_handshake_on_connect=False)
print("ok2")
​
cnt = 0
while True:
    cnt += 1
    print("Listen invocation: %d" % cnt)
    peer_address = scn.listen()
    if peer_address:
        print("Completed listening for peer: %s" % str(peer_address))
        break
​
print("Accepting...")
conn = scn.accept()[0]
sck.settimeout(5)
conn.get_socket(True).settimeout(5)
​
cnt = 0
while True:
    cnt += 1
    print("Listen invocation: %d" % cnt)
    peer_address = scn.listen()
    # assert not peer_address
    print("Handshake invocation: %d" % cnt)
    try:
        conn.do_handshake()
    except SSLError as err:
        if err.errno == 504:
            continue
        raise
    print("Completed handshaking with peer")
    break
​
cnt = 0
while True:
    cnt += 1
    # print("Listen invocation: %d" % cnt)
    peer_address = scn.listen()
    # assert not peer_address
    # print("Read invocation: %d" % cnt)
    # print("Hi there")
    try:
        message = conn.read()
    except SSLError as err:
        if err.errno == 502:
            continue
        if err.args[0] == SSL_ERROR_ZERO_RETURN:
            break
        raise
​
    data = message.decode()
    print("from client:%s"%data)
    cmd_filename = data.split(' ')
    if cmd_filename[0] != "ls" and cmd_filename[0] != "get":
        conn.write("please input True cmd")
        continue
    else:
        if cmd_filename[0] == "ls":
            obj = subprocess.Popen(data,shell=True,stdout=subprocess.PIPE)
            cmd_result = obj.stdout.read()
            conn.write(cmd_result)
        else:
            filename = cmd_filename[1]
            if filename[0] == "/":
                filedir = filename
            else:
                if filename[:2] == "./":
                    filename = filename[2:-1]
                filedir = path.join(current_path,filename)
            with open(filedir,"r") as fd:
                while True:
                    byte = fd.read(blocksize)
                    if not byte:
                        conn.write("Already Send".encode())
                        break
                    conn.write(byte.encode())
        
​
​
​
cnt = 0
while True:
    cnt += 1
    # print("Listen invocation: %d" % cnt)
    # peer_address = scn.listen()
    # assert not peer_address
    print("Shutdown invocation: %d" % cnt)
    try:
        s = conn.unwrap()
        s.close()
    except SSLError as err:
        if err.errno == 502:
            continue
        raise
    break
​
sck.close()
pass
​
​
#if __name__ == "__main__":
#    main()

client

檢視程式碼
from os import path
import ssl
from socket import socket, AF_INET, SOCK_DGRAM
from logging import basicConfig, DEBUG
​
basicConfig(level=DEBUG)  # set now for dtls import code
from dtls import do_patch
​
do_patch()
​
blocksize = 1024
#def main():
cert_path = path.join(path.abspath(path.dirname(__file__)), "certs")
s = ssl.wrap_socket(socket(AF_INET, SOCK_DGRAM), cert_reqs=ssl.CERT_NONE,
                    ca_certs=path.join(cert_path, "ca-cert_ec.pem"))
s.connect(('127.0.0.1', 28000))
try:
    while True:
        print("input ls <dir> to list files in dir.\n")
        print("input get <filename> to get files from dir.\n")
        send_msg = input(">")
        cmd, filename = send_msg.split(" ")
        try:
            s.send(send_msg.encode())
        except Exception as e:
            print("[-]Can not send Data")
        try:
            if cmd == "ls":
                data = s.recv(blocksize)
                print(data.decode())
            else:
                filename = filename.split("/")[-1]
                filedir = "./"+filename
                with open(filedir,"wb") as fd :
                    while True:
                        data = s.recv(blocksize)
                        if data.decode() == "Already Send":
                            print("Already Reveive.")
                            break
                        fd.write(data)
​
        except Exception as e:
            print("[-]Can not receive Data")
except KeyboardInterrupt:
    s.close()
    sys.exit(0)
​
#if __name__ == "__main__":
#    main()

 

1)啟動客戶端和服務端

python server/server.py
python client/client.py

2)服務端接受客戶端連線

並輸出握手訊息:

cys@ubuntu:~/NetworkSecurity/EXP1/dtls-src/dtls$ python server/server.py 
ok1
ok2
Listen invocation: 1
Completed listening for peer: ('127.0.0.1', 42416)
Accepting...
Completed handshaking with peer
​
cys@ubuntu:~/NetworkSecurity/EXP1/dtls-src/dtls$ python client/client.py 
DEBUG:dtls.util:Allocating BIO: 25437344
DEBUG:dtls.sslconnection:Allocating SSL CTX: 25710240
DEBUG:dtls.sslconnection:Allocating SSL: 26092656
DEBUG:dtls.sslconnection:Initiating handshake...
DEBUG:dtls.sslconnection:...completed handshake
input ls <dir> to list files in dir.
​
input get <filename> to get files from dir.
​
>

輸入檔名

3)客戶端從服務端下載檔案

過程截圖及程式碼:

client

ls ./
ls /
get 1.txt
get server.py

Server

獲取到了兩個檔案

檢視client檔案下有該檔案:

最終總的截圖:

4)通過Wireshark分析DTLS協議握手及通訊過程

抓取到Hello報文

抓取到cookie

抓取到金鑰協商過程

抓取到加密通訊的內容

python3.6安裝

apt-get install -y software-properties-common
add-apt-repository ppa:deadsnakes/ppa
apt-get update
apt-get install python3.6
cys@ubuntu:~$ python3.6 -m pip install python3-dtls
Collecting python3-dtls
  Using cached python3_dtls-1.3.0-py3-none-any.whl (102 kB)
Installing collected packages: python3-dtls
Successfully installed python3-dtls-1.3.0

10 傳送Change Cipher Spec訊息和Encrypted Handshake訊息的目的是什麼?

1.通知對端改變當前使用的加密方式,change cipher spec 實際可用於通知對端改版當前使用的加密通訊方式。

2.告訴對端自己在整個握手中收到了什麼資料,傳送了什麼資料,保證中間沒人篡改報文。首先,無論是客戶端還是服務端,都會在握手完成之後,傳送 Encrypted handshake message,且各自收到對端的Encrypted handshake message後會去驗證這個資料。 具體 這個 Encrypted handshake message 怎麼計算,就是把當前(準備傳送Encrypted handshake message)前,自己收到的資料和傳送的資料進行一次簡單運算(hash+加密)。如果中間有人篡改了報文,比如,把客戶端的client hello中的提供的加密套件改成了 一個弱祕鑰演算法,那麼對於server而言,收到的client hello 和 客戶端實際傳送的是不同的