1. 程式人生 > >openssl 建立證書的總結和注意事項

openssl 建立證書的總結和注意事項

1.該文章從網上看了好多部落格,並經過實踐形成。環境為ubuntu12和ubuntu14

"========================================大綱提要和注意事項================================================================="
1.注意事項:
1)OpenSSL庫中,各個函式的返回值的格式並不統一(有些用0表示失敗,有些用0表示成功),請注意區分;
2)用在OpenSSL的fd不能設定為nonblock,否則在SSL_connect時會失敗——感覺這一點限制了OpenSSL與除了libevent之外其他非同步I/O庫的適配
關於nonblock的問題,補充:可以在完成了SSL_connect/accept之後,將fd設定為nonblock

2.程式設計思想:
1)對程式來說,openssl將整個握手過程用一對函式體現,即客戶端的SSL_connect和服務端的SSL_accept.而後的應用層資料交換則用SSL_read和 SSL_write來完成
Linux下基於OpenSSL的SSL安全通訊設計

2)OpenSSL中的SSL安全通訊可以分為兩類,兩類基本上的操作相同,一類是建立SSL環境後使用BIO讀寫,另一類是直接在socket上建立SSL上下文環境。
本文主要討論在socket上建立SSL環境,以實現安全通訊。首先需要生成一對客戶機和伺服器證書,這可以使用openssl的命令實現。
可以建立一個模擬的CA,生成數字證書。如下:

3.證書通俗的說:分為兩類:(伺服器的證書和祕鑰); (客戶端的證書和祕鑰)。
  一般情況下:不需要使用客戶端的證書,(除非做銀行、金融方面的加密業務,類似U盾。),它的作用是驗證訊息是該客戶端發出的。

密碼互動情況如下圖:

"==========================================大綱提要和注意事項==============================================================="

"====================================自己試驗過的,成功速度最快的==========================================="
1.最開始應該修改配置檔案:一般我是修改/usr/local/ssl/openssl.cnf 這個配置檔案;
2.設定環境變數,生成證書時訪問這個配置檔案:OPENSSL_CONF=/usr/local/ssl/openssl.cnf; export OPENSSL_CONF;

******************************************************
x509證書一般會用到三類文,key,csr,crt。
Key 是私用金鑰openssl格,通常是rsa演算法。
Csr 是證書請求檔案,用於申請證書。在製作csr檔案的時,必須使用自己的私鑰來簽署申,還可以設定一個金鑰。
crt是CA認證後的證書文,(windows下面的,其實是crt),簽署人用自己的key給你簽署的憑證。

1.key的生成
openssl genrsa -des3 -out server.key 2048 (去掉中間的-des3可以生成不輸密碼的金鑰)
這樣是生成rsa私鑰,des3演算法,openssl格式,2048位強度。server.key是金鑰檔名。為了生成這樣的金鑰,需要一個至少四位的密碼。可以通過以下方法生成沒有密碼的key:
openssl rsa -in server.key -out server.key

server.key就是沒有密碼的版本了。

2. csr的生成方法
openssl req -new -key server.key -out server.csr
需要依次輸入國家,地區,組織,email。最重要的是有一個common name,可以寫你的名字或者域名。如果為了https申請,這個必須和域名吻合,否則會引發瀏覽器警報。生成的csr檔案交給CA簽名後形成服務端自己的證書。

3. 生成CA的crt
openssl req -new -x509 -key server.key -out ca.crt -days 3650 
生成的ca.crt檔案是用來簽署下面的server.csr檔案。 

4. crt生成方法
CSR檔案必須有CA的簽名才可形成證書,可將此檔案傳送到verisign等地方由它驗證,要交一大筆錢,何不自己做CA呢。
openssl x509 -req -days 3650 -in server.csr -CA ca.crt -CAkey server.key -CAcreateserial -out server.crt
輸入key的金鑰後,完成證書生成。-CA選項指明用於被簽名的csr證書,-CAkey選項指明用於簽名的金鑰,-CAserial指明序列號檔案,而-CAcreateserial指明檔案不存在時自動生成。
最後生成了私用金鑰:server.key和自己認證的SSL證書:server.crt

"====================================自己試驗過的,成功速度最快的==========================================="

"====================================TCP流協議與ssl訊息讀寫的異同==========================================="
1)SSL實現必須讀取整條記錄,哪怕select返回了一個位元組可讀,那麼ssl也要讀取整個記錄,這種基於紀錄的讀寫方式就是為了正確的加密個解密。因此
如果用select模型的話可能會出現一些莫名其妙的問題,

2)事實上也正是ssl訊息需要加密解密從而需要整個訊息整個訊息讀寫才使得ssl協議的行為和tcp的有了少有的不一致。
tcp的特點是流式傳輸,流式的特點就是沒有訊息邊界,一個連線就是一個流,需要應用程式自己去劃分自己的資料,舉個例子就是一端寫入x位元組,
對端可能讀出y位元組,具體多少要看網路狀況和視窗情況,tcp在這一點上是相當複雜的,應用程式的傳送只是簡單的將資料放入tcp的傳送緩衝區,
而接收只是簡單的從接收緩衝區中取回資料,反觀udp就不是這樣子,udp是基於資料報的,就是說不能分段,一端寫入多少另一端就讀出多少,當
然也可能永遠收不到,也可能亂序等等。現在看看ssl,它看起來好像是結合了tcp和udp的特點,它是有連線的,必須可靠傳輸並且按照順序收發,
但是在SSL record層面卻不是流式的(在API層面依然是流式的),每次呼叫SSL_read必須讀入一個ssl紀錄,一個ssl紀錄有一個固定大小的頭部(5位元組),
該頭部指示了訊息型別,ssl版本號以及訊息長度,首先需要讀出一個ssl訊息頭部,接下來就要在該頭部的訊息長度欄位的指導下進行訊息體的讀取,
而且必須讀取完整個完整訊息之後才能返回成功,否則均返回失敗,並且什麼都不做,ssl讀操作中,帶有頭的訊息是read的最小單位。ssl3_read_bytes
是openssl中SSL_read最終要呼叫的函式,它內部呼叫了ssl3_get_record:

"====================================TCP流協議與ssl訊息讀寫的異同==========================================="