歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux基礎 >> 關於Linux

Openssl應用編程

對於openssl應用編程這方面的詳細文檔很少,我是通過認真分析openssl源碼包中的示例代碼來學習並結合man文檔來理解它的基本結構的。SSL通訊模型為標准的C/S結構,除了在TCP層之上進行傳輸之外,與一般的通訊沒有什麼明顯的區別。下面我對用SSL建立安全的TCP連接的流程作一簡單分析。

一、數字證書准備

通常情況下我們的服務端需要

服務器端的私鑰server.key文件

服務器端證書server.crt文件

對於雙向認證連接,要用到

客戶端的私鑰client.key文件

客戶器端證書client.crt文件

對於單向認證連接,不需要用到戶端證書文件

二、 程序結構

與ssl有關的頭文件都放在openssl目錄下,通常需要用到這些:

#include /* SSLeay stuff */與RSA算法有關的一些定義

#include /*加密庫接口*/

#include /*證書文件相關*/

#include

#include

#include

1、對OPENSSL的一些必要的初始化

SSL_load_error_strings(); /*進行錯誤信息的初始化,不是必須的, 如果要使用OpenSSL的出錯信息打印,就要調用它*/

SSLeay_add_ssl_algorithms(); /*加載SSL算法庫*/

/*還可使用以下兩種方法加載SSL算法庫

SSL_library_init(void); 
OpenSSL_add_ssl_algorithms();

*/

創建SSL上下方環境

meth = SSLv23_server_method();

/*客戶端模式有:

SSL_METHOD* TLSv1_client_method(void);TLSv1.0協議 
SSL_METHOD* SSLv2_client_method(void);SSLv2協議 
SSL_METHOD* SSLv3_client_method(void);SSLv3協議 
SSL_METHOD* SSLv23_client_method(void);SSLv2/v3協議

服務端模式有:

SSL_METHOD* TLSv1_server_method(void); 
SSL_METHOD* SSLv2_server_method(void); 
SSL_METHOD* SSLv3_server_method(void); 
SSL_METHOD* SSLv23_server_method(void);

*/

ctx = SSL_CTX_new (meth); /*在應用中,客戶端和服務端必須為相同模式*/

ctx為返回的為當前SSL會話環境的指針,我們根據自己的需要對它進行設置:

void SSL_CTX_set_verify(SSL_CTX*, int, int* (int, X509_STORE_CTX*));

設置證書驗證的方式。第一個參數是當前的CTX指針,第二個是驗證方式,如果是要驗證對方的話,就使用SSL_VERIFY_PEER。不需要的話,使用 SSL_VERIFY_NONE.一般情況下,客戶端需要驗證對方,而服務器不需要。第三個參數是處理驗證的回調函數,如果沒有特殊的需要,使用空指針就可以了。

void SSL_CTX_load_verify_locations(SSL_CTX*, const char*, const char*);

加載證書,第一個參數同上,參數二是證書文件的名稱,參數三是證書文件的路徑;

int SSL_CTX_use_certificate_file(SSL_CTX* ctx, const char* file,int type);

加載本地的證書;type指明證書文件的結構類型;失敗返回-1

SSL_CTX_set_default_passwd_cb_userdata(ctx, "123456");

設置SSL要加載的證書的口令,如果不設置的話加載證書時會出提示符要求輸入口令的,這樣在程序中使用就比較麻煩,該函數就是預先將口令保存,在讀證書時自動使用。

int SSL_CTX_use_PrivateKey_file(SSL_CTX* ctx,const char* file,int type);

加載自己的私鑰;type參數指明私鑰文件的結構類型;失敗返回-1。加載了證書和文件之後,就可以驗證私鑰和證書是否相符:

int SSL_CTX_check_private_key(SSL_CTX*);

示例:

if (SSL_CTX_use_certificate_file(ctx, server.crt, SSL_FILETYPE_PEM) <= 0) {

ERR_print_errors_fp(stderr);

exit(3);

}

SSL_CTX_set_default_passwd_cb_userdata(ctx, "123456789");

if (SSL_CTX_use_PrivateKey_file(ctx, server.key, SSL_FILETYPE_PEM) <= 0) {

ERR_print_errors_fp(stderr);

exit(4);

}

if (!SSL_CTX_check_private_key(ctx)) {

fprintf(stderr,"Private key does not match the certificate public key/n");

exit(5);

}

2、關聯tcp套接字

SSL接連是依賴於socket套接字的,所以安全連接必須關聯相應套接字。SSL通信過程是在tcp連接建立之後進行的,所以套接字的建立過程跟普通的socket編程沒有什麼不同的,這裡不在贅述。

ssl = SSL_new (ctx); //申請SSL套接字

SSL_set_fd (ssl, sd); //綁定讀寫套接字

以上調用將連接成功的TCP套接字與SSL關聯。

3、開始安全通信

對於服務端調用

err = SSL_accept (ssl);

監聽客戶請求,對於客戶端調用

err = SSL_connect (ssl);

發起連接。成功之後,雙方就可以通過調用

int SSL_read(SSL* ssl, char* buf, int num); 
int SSL_write(SSL* ssl, char* buf, int num);

進行安全通信了。

此時雙方可通過調用X509* SSL_get_peer_certificate(SSL* ssl)來獲取對方的證書信息

示例:

client_cert = SSL_get_peer_certificate (ssl);

if (client_cert != NULL) {

printf ("Client certificate:/n");

str = X509_NAME_oneline (X509_get_subject_name (client_cert), 0, 0);

CHK_NULL(str);

printf ("/t subject: %s/n", str);

OPENSSL_free (str);

str = X509_NAME_oneline (X509_get_issuer_name (client_cert), 0, 0);

CHK_NULL(str);

printf ("/t issuer: %s/n", str);

OPENSSL_free (str);

/* We could do all sorts of certificate verification stuff here before

deallocating the certificate. */

X509_free (client_cert);

} else

printf ("Client does not have certificate./n");

4、通訊結束,需要釋放前面申請的SSL資源

int SSL_shutdown(SSL* ssl);關閉SSL套接字; 
void SSL_free(ssl);釋放SSL套接字; 
void SSL_CTX_free(ctx);釋放SSL環境;

Copyright © Linux教程網 All Rights Reserved