2017-2018-1 《信息安全系統設計基礎》實驗五 通訊協議設計

2017-2018-1 《信息安全系統設計基礎》實驗五 通訊協議設計

OpenSSL壓縮包、測試代碼test_openssl.c、客戶端/服務器等已上傳至個人碼雲😆,可供參考。html

————————CONTENTS————————


預備知識:OpenSSL簡介

『1、前言』linux

OpenSSL是爲網絡通訊提供安全及數據完整性的一種安全協議,囊括了主要的密碼算法、經常使用的密鑰和證書封裝管理功能以及SSL協議,並提供了豐富的應用程序供測試或其它目的使用。git

OpenSSL是一個強大的安全套接字層密碼庫,Apache使用它加密HTTPS,OpenSSH使用它加密SSH,可是,你不該該只將其做爲一個庫來使用,它仍是一個多用途的、跨平臺的密碼工具。github

1.基本功能

OpenSSL整個軟件包大概能夠分紅三個主要的功能部分:算法

  • 密碼算法庫
  • SSL協議庫
  • 應用程序

OpenSSL的目錄結構天然也是圍繞這三個功能部分進行規劃的。編程

做爲一個基於密碼學的安全開發包,OpenSSL提供的功能至關強大和全面,囊括了主要的密碼算法、經常使用的密鑰和證書封裝管理功能以及SSL協議,並提供了豐富的應用程序供測試或其它目的使用。segmentfault

2.輔助功能

  BIO機制是OpenSSL提供的一種高層IO接口,該接口封裝了幾乎全部類型的IO接口,如內存訪問、文件訪問以及Socket等。這使得代碼的重用性大幅度提升,OpenSSL提供API的複雜性也下降了不少。安全

  OpenSSL對於隨機數的生成和管理也提供了一整套的解決方法和支持API函數。隨機數的好壞是決定一個密鑰是否安全的重要前提。服務器

  OpenSSL還提供了其它的一些輔助功能,如從口令生成密鑰的API,證書籤發和管理中的配置文件機制等等。網絡

『2、證書』

證書就是數字化的文件,裏面有一個實體(網站、我的等)的公共密鑰和其餘的屬性,如名稱等。該公共密鑰只屬於某一個特定的實體,它的做用是防止一個實體僞裝成另一個實體。證書用來保證不對稱加密算法的合理性。

咱們如今經常使用的證書是採用X.509結構的,這是一個國際標準證書結構。任何遵循該標準的應用程序均可以讀寫X509結構的證書。經過檢查證書裏面的CA的名字,和CA的簽名,就知道這個證書的確是由該CA簽發的,而後,你就能夠簡單證書裏面的接收證書者的名字,而後提取公共密鑰。這樣作創建的基礎是,你信任該CA,認爲該CA沒有頒發錯誤的證書。

例如,一個證書的格式以下所示:

-----BEGIN CERTIFICATE-----
MIIC5jCCAk+gAwIBAgIUD+lk+DvSXyCqiJBxG24t1ShpSmgwDQYJKoZIhvcNAQEL
BQAwgYQxCzAJBgNVBAYTAmNoMRAwDgYDVQQIDAdiZWlqaW5nMRAwDgYDVQQHDAdi
ZWlqaW5nMRAwDgYDVQQKDAdmZW5ndGFpMQ8wDQYDVQQLDAZ4aW5jdW4xDDAKBgNV
BAMMA2R3ajEgMB4GCSqGSIb3DQEJARYRMjI1MDkyOTg0M0BxcS5jb20wHhcNMTcx
MjA2MTQwMjQyWhcNMjAxMjA1MTQwMjQyWjCBhDELMAkGA1UEBhMCY2gxEDAOBgNV
BAgMB2JlaWppbmcxEDAOBgNVBAcMB2JlaWppbmcxEDAOBgNVBAoMB2Zlbmd0YWkx
DzANBgNVBAsMBnhpbmN1bjEMMAoGA1UEAwwDZHdqMSAwHgYJKoZIhvcNAQkBFhEy
MjUwOTI5ODQzQHFxLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAvJz0
9d1vrKihyMnFvxq1DDEllRmMeoNnByZrA8t4usqTcjqD9JhZ8pc8PXOcYrvWDBtA
bEal3AJ53OXgTWUBYIE40CpbWJh49mdy30QOiG2PJa68PFSCMN4h4esXqpTsZd/p
raQIcFgV0Lv4/oirdviHMxKdU4Fg3R8lNK4Bm4MCAwEAAaNTMFEwHQYDVR0OBBYE
FGlNsxsqIlUMKaJW+vUb6xbyDVxAMB8GA1UdIwQYMBaAFGlNsxsqIlUMKaJW+vUb
6xbyDVxAMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADgYEAfcvw0JRX
fXyZEukZmNpY1fSlMFQ62e+kQa10V6n56fpxV2ZtyhwPy6nwXBF2iJQpSzmKDAJe
NWDtKhUnxg8rOi7TK33m4CfXkB/KbPY//Xhx0x+vZ9EYf3x/9dLIS02WCy/vweWy
Igs3aBoNuj4jjjp/Dp70EnguuvIUnr8eBFo=
-----END CERTIFICATE-----

『3、經常使用指令』

openssl有衆多子命令,分爲三類:

  • 標準命令
  • 消息摘要(dgst子命令)
  • 加密命令(enc子命令)

詳細的命令總結能夠參考:OpenSSL簡介,這裏以一個命令爲例進行簡單介紹。

先生成本身的私有密鑰文件,好比叫server.key:

openssl genrsa -des3 -out server.key 1024

genras表示生成RSA私有密鑰文件,-des3表示用DES3加密該文件,1024是咱們的key的長度。基於如今的計算機速度而言,通常用512就能夠了,784可用於商業行爲,1024能夠用於軍事用途了。生成server.key的時候會要求輸入密碼,這個密鑰用來保護server.key文件,這樣即便server.key文件被竊取,也打不開,拿不到私鑰。

openssl rsa -noout -text -in server.key

若是你以爲server.key的保護密碼太麻煩想去掉的話:

openssl rsa -in server.key -out server.key.unsecure(不過不推薦這麼作)

下一步要獲得證書了。獲得證書以前咱們要生成一個Certificate Signing Request。CA只對CSR進行處理。

openssl req -new -key server.key -out server.csr

生成CSR的時候屏幕上將有提示,依照其指示一步一步輸入要求的信息便可。生成的csr文件交給CA簽名後造成服務端本身的證書。

返回目錄


任務一 Linux下OpenSSL的安裝與測試

任務要求:在Ubuntu中完成 http://www.cnblogs.com/rocedu/p/5087623.html 中的做業

『1、安裝指南』

  • 在Linux下使用unzip openssl-master.zip命令解壓,以下圖所示:

  • 安裝的具體命令以下:
$ ./config
$ make
$ make test
$ make install

等待安裝完畢便可。若是安裝過程當中出現任何問題,均可以參考其目錄下「INSTALL」的相應安裝說明解決。

『2、安裝測試』

  • 編寫一個測試代碼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命令編譯,生成「test_openssl」可執行文件,運行程序,並執行echo $?,結果打印0,測試結果代表安裝成功。

【對編譯命令的一點說明:-L選項——指定連接庫的文件夾地址;-lcrypto——導入OpenSSL所需包;-ldl選項——加載動態庫;-lpthread選項——連接POSIX thread庫】

『3、可能出現的問題及解決』

編譯時可能會出現test_openssl.c:(.text+0xf):對‘OPENSSL_init_crypto’未定義的引用等「未定義的引用」問題。除去代碼編寫出錯的狀況,大多數是由於沒有連接相應的庫,或者順序錯誤。好比首次編譯「test_openssl.c」出現如下錯誤:

解決方法:將「openssl-master」文件夾下的「libcrypto.a」和「libssl.a」放在/usr/local/ssl/lib目錄下(注意使用sudo權限),編譯時連接這個目錄便可。

在後面若遇到相似的「未定義的引用」問題,首先應考慮是否連接相應的庫,或連接的順序是否正確(好比-lssl、-lcrypto要寫在-ldl、-lpthread前面等)。

返回目錄


任務二 混合密碼系統防禦

任務要求:在Ubuntu中實現對實驗二中的「wc服務器」經過混合密碼系統進行防禦

『1、OpenSSL函數介紹』

OpenSSL是一個開放源代碼的SSL協議的產品實現,它採用C語言做爲開發語言,具有了跨系統的性能。調用OpenSSL的函數就能夠實現一個SSL加密的安全數據傳輸通道,從而保護客戶端和服務器之間數據的安全。

  • 頭文件:
#include <openssl/ssl.h>
#include <openssl/err.h>

基於OpenSSL的程序都要遵循如下幾個步驟:

(1)OpenSSL初始化:

在使用OpenSSL以前,必須進行相應的協議初始化工做,能夠經過下面的函數實現:

int SSL_library_int(void);

(2)選擇會話協議:

在利用OpenSSL開始SSL會話以前,須要爲客戶端和服務器制定本次會話採用的協議,目前可以使用的協議包括TLSv1.0、SSLv二、SSLv三、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);//關閉SSL套接字
void SSl_free(SSL *ssl);//釋放SSL套接字
void SSL_CTX_free(SSL_CTX *ctx); //釋放SSL會話環境

『2、OpenSSL應用編程框架』

下面大體的僞代碼說明了調用SSL的一整個流程:

  • Client端:
ctx = SSL_CTX_new (SSLv23_client_method());
ssl = SSL_new (ctx);
fd = socket ();
connect ();
SSL_set_fd (ssl, fd);
SSL_connect (ssl);
SSL_write ();
  • Server端:
ctx = SSL_CTX_new (SSLv23_server_method());
ssl = SSL_new (ctx);
fd = socket ();
bind ();
listen ();
accept ();
SSL_set_fd (ssl, fd);
SSL_accept (ssl);
SSL_read ();

【產品代碼詳見碼雲:實驗五

  • 編譯方式:
gcc -o server server.c -I /usr/local/ssl/include -L/usr/local/ssl/lib -lssl -lcrypto -ldl -lpthread

gcc -o telent telent.c -I /usr/local/ssl/include -L/usr/local/ssl/lib -lssl -lcrypto -ldl -lpthread
  • 生產私鑰和證書
openssl genrsa -out privkey.pem 1024
openssl req -new -x509 -key privkey.pem -out CAcert.pem -days 1095
  • 程序運行方式:
./server 7838 1 CAcert.pem privkey.pem
./telent 127.0.0.1 7838
  • 運行截圖:

返回目錄


參考資料

返回目錄

···To Be Continued😋···

相關文章
相關標籤/搜索