win32平臺下研究除錯SSL通訊機制

DayThinking發表於2012-11-22

    SSL協議為了解決在網路中的實體認證和資訊的加密傳輸,為了做到這兩點,基於SSL協議的通訊需要進行若干次的握手協商(點選檢視),這麼多的握手步驟概括來說分為三步:1.雙方交換證書來確保彼此的身份;2.身份確認後進行會話通訊金鑰的協商(詳見附錄二);3.協商出會話金鑰後用其進行加密傳輸資訊。

Openssl是SSL協議的一個實現庫,關於OpenSSL的功能與簡介在此我就不多介紹了,詳細可以觀看我的另一篇博文:OpenSSL簡介

程式介紹及目的:

程式分為兩部分,客戶端和伺服器端,我們的目的是利用SSL/TLS的特性保證通訊雙方能夠互相驗證對方身份(真實性),並保證資料的完整性, 私密性。

一、程式的框架:

1.客戶端程式的框架為:

/*生成一個SSL結構*/

meth = SSLv23_client_method();

ctx = SSL_CTX_new (meth);

ssl = SSL_new(ctx);

/*下面是正常的socket過程*/

fd = socket();

connect();

/*把建立好的socketSSL結構聯絡起來*/

SSL_set_fd(ssl,fd);

/*SSL的握手過程*/

SSL_connect(ssl);

/*接下來用SSL_write(), SSL_read()代替原有的write(),read()即可*/

SSL_write(ssl,"Hello world",strlen("HelloWorld!"));


2.服務端程式的框架為:

/*生成一個SSL結構*/

meth = SSLv23_server_method();

ctx = SSL_CTX_new (meth);

ssl = SSL_new(ctx);

/*下面是正常的socket過程*/

fd = socket();

bind();

listen();

accept();

/*把建立好的socketSSL結構聯絡起來*/

SSL_set_fd(ssl,fd);

/*SSL的握手過程*/

SSL_connect(ssl);

/*接下來用SSL_write(), SSL_read()代替原有的write(),read()即可*/

SSL_read (ssl, buf, sizeof(buf));

對程式來說,openssl將整個握手過程用一對函式體現,即客戶端的SSL_connect和服務端的SSL_accept.而後的應用層資料交換則用SSL_read SSL_write來完成.

二、證書檔案生成

    基於SSL協議的應用必然會涉及到數字證書,可以說二者必然同存亡,因為在網路中證明某個實體身份的只有數字證書,而ssl協議解決的問題之一就是要跟正確的人進行保密的資訊傳輸,因此在確定對方就是正確的通訊目標時只能用數字證書來驗證,所以除將第一步的程式編譯成功外,還需生成必要的證書和私鑰檔案使雙方能夠成功驗證對方,步驟如下。

1、前期準備:

在生成證書的目錄(即:包含OpenSSL.exe檔案的目錄)下建立幾個檔案和資料夾,有
./demoCA/
./demoCA/newcerts/
./demoCA/private/
./demoCA/index.txt (空檔案,生成證書時會將資料記錄寫入)
./demoCA/serial (在serial檔案中寫入第一個序列號“01”,在生成證書時會以此遞增)或在openssl的配置檔案中搜尋這個檔案拷貝到這裡。

安裝完成後將openssl\bin新增到環境變數path中,可方便使用

注意:cnf副檔名會被作業系統當成快捷方式,看不到副檔名,在dos下使用dir就可以看到。

進入cmd後輸入openssl可能會提示

WARNING: can't open config file: /usr/local/ssl/openssl.cnf

提示找不到openssl.cnf ,沒有關係在輸入openssl命令前新增環境變數OPENSSL_CONF即可。

set OPENSSL_CONF=openssl.cnf

一般使用openssl.cnf預設配置即可無需修改。openssl.cnf檔案在bin目錄裡,但是其樣例檔案一般會以.cfg或.example等作字尾,更改過來即可。

概念:首先要有一個根證書,然後用根證書來簽發使用者證書。
      使用者進行證書申請:一般先生成一個私鑰,然後用私鑰生成證書請求(證書請求裡應含有公鑰資訊),再利用證書伺服器的根證書來簽發證書。

特別說明:
(1)自簽名證書(一般用於頂級證書、根證書): 證書的名稱和認證機構的名稱相同.
(2)根證書:根證書是CA認證中心給自己頒發的證書,是信任鏈的起始點。安裝根證書意味著對這個CA認證中心的信任

數字證書是由證書認證機構(CA)對證書申請者真實身份驗證之後,用CA的根證書對申請人的一些基本資訊以及申請人的公鑰進行簽名(相當於加蓋發證書機構的公章)後形成的一個數字檔案。數字證書包含證書中所標識的實體的公鑰(就是說你的證書裡有你的公鑰),由於證書將公鑰與特定的個人匹配,並且該證書的真實性由頒發機構保證(就是說可以讓大家相信你的證書是真的),因此,數字證書為如何找到使用者的公鑰並知道它是否有效這一問題提供瞭解決方案。

openssl中有如下字尾名的檔案:
.key格式:私有的金鑰
.csr格式:證書籤名請求(證書請求檔案),含有公鑰資訊,certificate signing request的縮寫
.crt格式:證書檔案,certificate的縮寫
.crl格式:證書吊銷列表,Certificate Revocation List的縮寫
.pem格式:用於匯出,匯入證書時候的證書的格式,有證書開頭,結尾的格式

常用證書協議:

x509v3: IETF的證書標準
x.500: 目錄的標準
SCEP:  簡單證書申請協議,用http來進行申請,資料有PKCS#7封裝,資料格式其實也是PKCS#10。
PKCS#7:是封裝資料的標準,可以放置證書和一些請求資訊,關於P7及下面設計到的P10和P12在Openssl裡面其實就是一個結構體,可以檢視這些結構體加以理解。
PKCS#10:用於離線證書申請的證書申請的資料格式,證書申請者產生一個密碼對,將公鑰組織到P10結構中並用私鑰對其進行簽名,將簽名值也組織到P10結構中,在Openssl裡面對應的結構體是X509_REQ,注意資料包是使用PKCS#7封裝這個資料。
PKCS#12:用於一個單一檔案中交換公共和私有物件,就是公鑰,私鑰和證書,這些資訊進行打包,加密放在儲存目錄中,CISCO放在NVRAM中,使用者可以匯出,以防證書伺服器掛掉可以進行相應恢復。思科是.p12,微軟是.pfx.
2、具體步驟詳見:http://blog.csdn.net/fyang2007/article/details/6180361。這是我按照這個操作自己製作的證書,證明是可行的,我已經在程式中測試過。中間所用到的密碼統一為:123456.
證書檔案下載地址
在輸入資訊驗證時,需要注意common name為:127.0.0.1.

這一部分非常關鍵,涉及到證書的形成,我當初耗時很久才解決這些證書檔案,希望學習者慢慢除錯,如有問題歡迎交流:2006sszgg@163.com.

三、程式碼實現(win32版本)

程式碼我已經上傳,學習的朋友歡迎去下載
中間輸入的密碼統一都是:123456.我已經測試過,可以執行。

四、SSL/TLS中的金鑰:

在HTTPS協議中,客戶端與服務端進行對稱的對話金鑰協商過程中,為嘛需要三個隨機數來生成”會話金鑰”,dog250解釋得很好:“不管是客戶端還是伺服器,都需要隨機數,這樣生成的金鑰才不會每次都一樣。由於SSL協議中證書是靜態的,因此十分有必要引入一種隨機因素來保證協商出來的金鑰的隨機性。對於RSA金鑰交換演算法來說,pre-master-key本身就是一個隨機數,再加上hello訊息中的隨機,三個隨機數通過一個金鑰匯出器最終匯出一個對稱金鑰。
pre master key的存在在於SSL協議不信任每個主機都能產生完全隨機的隨機數,如果隨機數不隨機,那麼pre master secret就有可能被猜出來,那麼僅適用pre master secret作為金鑰就不合適了,因此必須引入新的隨機因素,那麼客戶端和伺服器加上pre master secret三個隨機數一同生成的金鑰就不容易被猜出了,一個偽隨機可能完全不隨機,可是是三個偽隨機就十分接近隨機了,每增加一個自由度,隨機性增加的可不是一。”

預主金鑰、主金鑰和會話金鑰,這幾個金鑰都是有聯絡的。
對於RSA來說,預主金鑰是客戶端生成,加密之後發給伺服器,伺服器用私鑰來解密。
對於ECDHE來說,預主金鑰是雙方通過橢圓曲線演算法來生成。
主金鑰是由預主金鑰、客戶端隨機數和伺服器隨機數通過PRF函式來生成;會話金鑰是由主金鑰、客戶端隨機數和伺服器隨機數通過PRF函式來生成,會話金鑰裡面包含對稱加密金鑰、訊息認證和CBC模式的初始化向量,但對於非CBC模式的加密演算法來說,就沒有用到這個初始化向量。


附錄一.參考文獻有

1.openssl 生成證書【整理】
2.pdf文件ssl與tsl.
3.解密https的建立過程

附錄二.對稱金鑰協商相關的文章

1.Https SSL/TLS PreMaster/MasterSecret(Key)計算
2.Premaster secret and master key in OpenSSL
3.讓SSL/TLS協議流行起來:深度解讀SSL/TLS實現
4.掃盲 HTTPS 和 SSL/TLS 協議[3]:金鑰交換(金鑰協商)演算法及其原理
5. 一個簡單的DH金鑰協商演算法的實現
6.SM2演算法第二十二篇:DH與ECDH祕鑰協商原理
7. HTTPS 協議和原理
8.基於TLS1.3的微信安全通訊協議mmtls介紹
9.https會話過程中金鑰的計算

附錄三.https協議的優化
1.讓大象起舞:HTTPS 計算效能優化

附錄四.免費第三方數字證書
1.推薦一個免費申請且瀏覽器認可的數字證書籤髮網站:Let's Encrypt這篇文章有詳細的申請流程。



相關文章