2017-2018-1 20155338 信息安全系統設計基礎》實驗五 通信協議設計
2017-2018-1 20155338 信息安全系統設計基礎》實驗五 通信協議設計
實驗要求:
任務一:Linux下OpenSSL的安裝與使用
在Ubuntu中完成(http://www.cnblogs.com/rocedu/p/5087623.html)中的作業
兩人一組:
1、基於Socket實現TCP通信,一人實現服務器,一人實現客戶端
2、研究OpenSSL算法,測試對稱算法中的AES,非對稱算法中的RSA,Hash算法中的MD5
3、選用合適的算法,基於混合密碼系統實現對TCP通信進行機密性、完整性保護。
4、學有余力者,對系統進行安全性分析和改進。
1、完成過程:
1、通過老師提供的鏈接進行下載Linux下OpenSSL的安裝與使用,並安裝
2、安裝成功後用命令行解壓
3、解壓源代碼:tar xzvf openssl-1.1.0-pre1.tar.gz
4、進入源代碼目錄:cd openssl-1.1.0-pre1
5、使用下列命令編譯安裝:
./config
make
make test
make install
6、完成上述步驟,openssl-1.1.0就安裝好了。
- 編寫一個測試代碼test_openssl.c:
#include <stdio.h> #include <openssl/evp.h> int main(){ OpenSSL_add_all_algorithms(); return 0; }
然後進行編譯並運行:
gcc -o test_openssl test_openssl.c -L/usr/local/ssl/lib -lcrypto -ldl -lpthread
echo $?
“-L”之後指定的是鏈接庫的路徑,由於要導入OpenSSL所以使用-lcrypto參數
運行結果如下:
return 0了則說明安裝成功。
2、基於Socket實現TCP通信
socket的基本操作:
socket()函數、bind()函數、listen()、connect()函數、accept()函數、read()、write()函數等。
bind()函數把一個地址族中的特定地址賦給socket。例如對應AF_INET、AF_INET6就是把一個ipv4或ipv6地址和端口號組合賦給socket。
TCP服務器端依次調用socket()、bind()、listen()之後,就會監聽指定的socket地址了。
運行截圖如下:
3、通過openssl測試密碼算法(上傳到藍墨雲上的作業中圖片可能不是很清晰,但放的也是原圖,不知是什麽原因,這裏放上清晰的)
這裏我選擇了非對稱密碼算法的RSA,Hash算法中的MD5。
測試RSA:
創建一個文本文件,裏面輸入123456:**openssl enc -aes-128-cbc -in plain.txt -out out.txt -pass file:passwd.txt**
生成rsa私鑰文件:openssl genrsa -out rsaprivatekey.pem 1024
生成公鑰文件,指明輸出文件是公鑰文件:openssl rsa -in rsa_private_key.pem -pubou -out rsa_private_key.pem
用公鑰匙rsa_private_key.pem加密文件readme.txt,輸出到文件hello.en:openssl rsautl -encrypt -in readme.txt -inkey rsa_private_key.pem -pubin -out hello.en
使用私鑰匙rsa_private_key.pem解密密文hello.en輸出到文件hello.de: openssl rsautl -decrypt -in hello.en -inkey rsa_private_key.pem -pubin -out hello. de
結果如下:
測試md5:
echo "plain.txt" | openssl dgst -md5
結果如下:
任務二:
在Ubuntu中實現對實驗二中的“wc服務器”通過混合密碼系統進行防護
提交測試截圖
基於OpenSSL的程序都要遵循以下幾個步驟:
(1)、OpenSSL初始化:
在使用OpenSSL之前,必須進行相應的協議初始化工作,可以通過下面的函數實現:
int SSL_library_int(void);
(2)選擇會話協議:
在利用OpenSSL開始SSL會話之前,需要為客戶端和服務器制定本次會話采用的協議,目前能夠使用的協議包括TLSv1.0、SSLv2、SSLv3、SSLv2/v3。
需要註意的是,客戶端和服務器必須使用相互兼容的協議,否則SSL會話將無法正常進行。
(3)創建會話環境:
在OpenSSL中創建的SSL會話環境稱為CTX,使用不同的協議會話,其環境也不一樣的。
- 申請SSL會話環境的OpenSSL函數是:
SSL_CTX SSL_CTX_new(SSL_METHOD method);
當SSL會話環境申請成功後,還要根據實際的需要設置CTX的屬性,通常的設置是指定SSL握手階段證書的驗證方式和加載自己的證書。
- 制定證書驗證方式的函數是:
int SSL_CTX_set_verify(SSL_CTX *ctx,int mode,int(*verify_callback),int(X509_STORE_CTX *));
- 為SSL會話環境加載CA證書的函數是:
SSL_CTX_load_verify_location(SSL_CTX *ctx,const char *Cafile,const char *Capath);
- 為SSL會話加載用戶證書的函數是:
SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file,int type);
- 為SSL會話加載用戶私鑰的函數是:
SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx,const char* file,int type);
- 在將證書和私鑰加載到SSL會話環境之後,就可以調用下面的函數來驗證私鑰和證書是否相符:
int SSL_CTX_check_private_key(SSL_CTX *ctx);
(4)建立SSL套接字
SSL套接字是建立在普通的TCP套接字基礎之上,在建立SSL套接字時可以使用下面的一些函數:
SSL *SSl_new(SSL_CTX *ctx);//申請一個SSL套接字
int SSL_set_fd(SSL *ssl,int fd);)//綁定讀寫套接字
int SSL_set_rfd(SSL *ssl,int fd);//綁定只讀套接字
int SSL_set_wfd(SSL *ssl,int fd);//綁定只寫套接字
(5)完成SSL握手
在成功創建SSL套接字後,客戶端應使用函數SSL_connect( )替代傳統的函數connect( )來完成握手過程:
int SSL_connect(SSL *ssl);
而對服務器來講,則應使用函數SSL_ accept ( )替代傳統的函數accept ( )來完成握手過程:
int SSL_accept(SSL *ssl);
握手過程完成之後,通常需要詢問通信雙方的證書信息,以便進行相應的驗證,這可以借助於下面的函數來實現:
X509 *SSL_get_peer_certificate(SSL *ssl);
該函數可以從SSL套接字中提取對方的證書信息,這些信息已經被SSL驗證過了。
X509_NAME *X509_get_subject_name(X509 *a);
該函數得到證書所用者的名字。
(6)進行數據傳輸
當SSL握手完成之後,就可以進行安全的數據傳輸了,在數據傳輸階段,需要使用SSL_read( )和SSL_write( )來替代傳統的read( )和write( )函數,來完成對套接字的讀寫操作:
int SSL_read(SSL *ssl,void *buf,int num);
int SSL_write(SSL *ssl,const void *buf,int num);
(7)結束SSL通信
當客戶端和服務器之間的數據通信完成之後,調用下面的函數來釋放已經申請的SSL資源:
int SSL_shutdown(SSL *ssl);
void SSl_free(SSL *ssl);
void SSL_CTX_free(SSL_CTX *ctx);
運行截圖:
參考資料:
openssl證書生產過程
Linux 中的 Openssl命令及實例代碼
OpenSSL程序編寫步驟
2017-2018-1 20155338 信息安全系統設計基礎》實驗五 通信協議設計