Linux安全體系學習筆記之三:OpenSSL源代碼分析(2)

火星人 @ 2014-03-03 , reply:0


Linux安全體系學習筆記之三:OpenSSL源代碼分析(2)


Linux安全體系學習筆記之三:OpenSSL源代碼分析(2)



SSL工作方式:雙向證書認證的SSL握手過程。
以下簡要介紹SSL協議的工作方式。客戶端要收發幾個握手信號:
1、發送一個「ClientHello」消息,說明它支持的密碼演算法列表、壓縮方法及最高協議版本,也發送稍後將被使用的隨機數。
2、然後收到一個「ServerHello」消息,包含伺服器選擇的連接參數,源自客戶端初期所提供的「ClientHello」。
3、當雙方知道了連接參數,客戶端與伺服器交換證書(依靠被選擇的公鑰系統)。這些證書通常基於X.509,不過已有草案支持以OpenPGP為基礎的證書。
4、伺服器請求客戶端公鑰。客戶端有證書即雙向身份認證,沒證書時隨機生成公鑰。
5、客戶端與伺服器通過公鑰保密協商共同的主私鑰(雙方隨機協商),這通過精心謹慎設計的偽隨機數功能實現。結果可能使用Diffie-Hellman交換,或簡化的公鑰加密,雙方各自用私鑰解密。所有其他關鍵數據的加密均使用這個「主密鑰」。

數據傳輸中記錄層(Record layer)用於封裝更高層的HTTP等協議。記錄層數據可以被隨意壓縮、加密,與消息驗證碼壓縮在一起。每個記錄層包都有一個Content-Type段用以記錄更上層用的協議。

使用SSL層介面函數有以下幾個步驟:

1、初始化OpenSSL庫

初始化函數列出如下:#define OpenSSL_add_ssl_algorithms()SSL_library_init()
#define SSLeay_add_ssl_algorithms()  SSL_library_init()2、選擇會話協議

客戶端使用下面的函數選擇會話協議:const SSL_METHOD *SSLv2_client_method(void);/* SSLv2 */


const SSL_METHOD *SSLv3_client_method(void);/* SSLv3 */


const SSL_METHOD *SSLv23_client_method(void);/* SSLv3 but can rollback to v2 */


const SSL_METHOD *TLSv1_client_method(void);/* TLSv1.0 */


const SSL_METHOD *DTLSv1_client_method(void);/* DTLSv1.0 */伺服器端使用下面的函數選擇會話協議:
const SSL_METHOD *SSLv2_server_method(void);/* SSLv2 */
const SSL_METHOD *SSLv3_server_method(void);  /* SSLv3 */
const SSL_METHOD *SSLv23_server_method(void);  /* SSLv3 but can rollback to v2 */
const SSL_METHOD *TLSv1_server_method(void);  /* TLSv1.0 */
const SSL_METHOD *DTLSv1_server_method(void);  /* DTLSv1.0 */
3、創建會話環境

創建會話環境:SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth);設置證書驗證方式:void SSL_CTX_set_verify(SSL_CTX *ctx,int mode,
int (*callback)(int, X509_STORE_CTX *));給會話環境載入CA證書:int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x);
int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d);
給會話環境載入用戶私鑰:int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey);
int SSL_CTX_use_PrivateKey_ASN1(int pk,SSL_CTX *ctx,
const unsigned char *d, long len);驗證私鑰和證書是否相符:int SSL_CTX_check_private_key(const SSL_CTX *ctx);4、建立SSL套接字

SSL套接字建立在普通的TCP套接字基礎上,應用程序在創建普通套接字、得到套接字描述符fd之後,再創建SSL套接字,並將fd綁定在SSL套接字上。SSL *SSL_new(SSL_CTX *ctx);


intSSL_set_fd(SSL *s, int fd);
int  SSL_set_rfd(SSL *s, int fd);
int  SSL_set_wfd(SSL *s, int fd);5、完成SSL握手

與普通socket編程類似,創建SSL套接字后,客戶端使用SSL_connect替代普通socket的connect函數,伺服器端則以SSL_accept代替普通socket的accept()函數。int
SSL_accept(SSL *ssl);
int SSL_connect(SSL *ssl);握手完成之後,詢問通信雙方的證書信息:X509 *SSL_get_peer_certificate(const SSL *s);


X509_NAME *X509_get_subject_name(X509 *a);  // 6、數據傳輸

對數據的安全傳輸包括了加密/解密、壓縮/解壓縮的過程。int
SSL_read(SSL *ssl,void *buf,int num);
int SSL_peek(SSL *ssl,void *buf,int num);
int SSL_write(SSL *ssl,const void *buf,int num);7、SSL通信結束

關閉SSL套接字、釋放會話環境。int SSL_shutdown(SSL *s);

voidSSL_free(SSL *ssl);


voidSSL_CTX_free(SSL_CTX *);
《解決方案》

謝謝博主



[火星人 via ] Linux安全體系學習筆記之三:OpenSSL源代碼分析(2)已經有154次圍觀

http://www.coctec.com/docs/service/show-post-1322.html