SSL編程簡介

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

頭文件:c++

#include <openssl/ssl.h>
#include <openssl/err.h>

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

int SSL_library_int(void);

在開始SSL會話以前,須要爲客戶端和服務器制定本次會話採用的協議,目前可以使用的協議包括TLSv1.0SSLv2SSLv3SSLv2/v3。須要注意的是,客戶端和服務器必須使用相互兼容的協議,不然SSL會話將沒法正常進行。segmentfault

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會話加載用戶證書的函數是:socket

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);

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); // 綁定只寫套接字

在成功建立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);

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);

當客戶端和服務器之間的數據通訊完成以後,調用下面的函數來釋放已經申請的SSL資源:

int SSL_shutdown(SSL *ssl); // 關閉SSL套接字
void SSl_free(SSL *ssl); // 釋放SSL套接字
void SSL_CTX_free(SSL_CTX *ctx);  // 釋放SSL會話環境

客戶端程序的框架:

meth = SSLv23_client_method();  
ctx = SSL_CTX_new(meth);  
ssl = SSL_new(ctx);  
fd = socket();  
connect();  
SSL_set_fd(ssl, fd);  
SSL_connect(ssl);  
SSL_write(ssl, "Hello world", strlen("Hello World!"));

服務端程序的框架:

meth = SSLv23_server_method();  
ctx = SSL_CTX_new(meth);  
ssl = SSL_new(ctx);  
fd = socket();  
bind();  
listen();  
accept();  
SSL_set_fd(ssl, fd);  
SSL_connect(ssl);  
SSL_read(ssl, buf, sizeof(buf));

OpenSSL中的SSL安全通訊能夠分爲兩類,兩類基本上的操做相同,一類是創建SSL環境後使用BIO讀寫,另外一類是直接在socket上創建SSL上下文環境。在OpenSSL的安裝目錄下的misc目錄下,運行腳本sudo ./CA.sh -newca,根據提示填寫信息完成後會生成一個demoCA的目錄,裏面存放了CA的證書和私鑰。

生成客戶端和服務器證書申請:

$ openssl req -newkey rsa:1204 -out sslclientreq.pem -keyout sslclientkey.pem
$ openssl req -newkey rsa:1204 -out sslserverreq.pem -keyout sslserverkey.pem

簽發客戶端和服務器證書:

$ openssl ca -in sslclientreq.pem -out sslclientcert.pem
$ openssl ca -in sslserverreq.pem -out sslservercert.pem

參考文章

Ubuntu使用OpenSSL生成數字證書詳解
SSL編程- 簡單函數介紹
SSL/TLS原理詳解
SSL握手通訊詳解及linux下c/c++ SSL Socket

相關文章
相關標籤/搜索