OpenSSL
是一個開放源代碼的SSL
協議實現,採用C
語言做爲開發語言,具有了跨系統的性能。調用OpenSSL
的函數就能夠實現一個SSL
加密的安全數據傳輸通道,從而保護客戶端和服務器之間數據的安全。linux
頭文件:c++
#include <openssl/ssl.h> #include <openssl/err.h>
在使用OpenSSL
以前,必須進行相應的協議初始化工做,這能夠經過下面的函數實現:編程
int SSL_library_int(void);
在開始SSL
會話以前,須要爲客戶端和服務器制定本次會話採用的協議,目前可以使用的協議包括TLSv1.0
、SSLv2
、SSLv3
、SSLv2/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