ssl介紹以及雙向認證和單向認證原理

最近在做android的https通信,需要用到ssl的雙向認證,之前這一塊兒沒有仔細研究過,在網上找了一篇比較不錯的介紹文章,搬運到這兒來,以備後面查詢。

本文章轉載自:CU 感謝原作者:fortara

證書介紹

SSL安全證書可以自己生成,也可以通過第三方的CACertification Authority)認證中心付費申請頒發。

SSL安全證書包括:

1.       CA證書,也叫根證書或中間級證書。單向認證的httpsCA證書是可選的。主要目的是使證書構成一個證書鏈,以達到瀏覽器信任證書的目的。如果使用了CA證書,服務器證書和客戶證書都使用CA證書來簽名。如果不安裝CA證書,瀏覽器默認認爲是不安全的。

2.       服務器證書。必選。通過服務器私鑰,生成證書請求文件CSR,再通過CA證書籤名生成服務器證書。

3.       客戶證書。可選。如果有客戶證書,就是雙向認證的HTTPS,否則就是單向認證的HTTPS。生成步驟和服務器證書類似。

上面幾種證書都可以自己生成。商業上,一般自己提供服務器或客戶證書端的私鑰和證書請求CSR,向第三方機構付費申請得到通過CA證書籤名的服務器證書和客戶證書。

 

生成證書

openssl提供的工具CA.sh簽名證書,證書放在/usr/local/apache2/conf/ssl.crt目錄,先把工具拷貝過來:

cp /usr/share/ssl/misc/CA.sh /usr/local/apache2/conf/ssl.crt

 

1.       CA證書(根證書/中間級證書)

CA認證機構提供,如果是雙向認證則必選,否則是可選。通過CA證書,構成一個證書鏈,目的是使瀏覽器信任你的證書。如果使用了CA證書,用它來簽名服務器和客戶證書,以達到瀏覽器信任的目的。

自己生成CA證書步驟:

./CA.sh –newca

回車創建新文件,輸入加密密碼,並填寫證書信息:

Country Name (2 letter code) [AU]:CN

State or Province Name (full name) [Some-State]:Guangdong

Locality Name (eg, city) []:Shenzhen

Organization Name (eg, company) [Internet Widgits Pty Ltd]:xxx

Organizational Unit Name (eg, section) []:xxx

Common Name (eg, YOUR name) []:www.shenmiguo.com 

Email Address []:[email protected]

Common Name填入主機全稱是比較好的選擇。這個名稱必須與通過瀏覽器訪問您網站的URL完全相同,否則用戶會發現您服務器證書的通用名與站點的名字不匹配,用戶就會懷疑您的證書的真實性。服務器證書和客戶證書的Common Name應該和CA一致。

生成結果:demoCA/private/cakey.pemCA證書的私鑰文件,demoCA/cacert.pemCA證書。

這樣就建好了一個CA服務器,有了一個根證書的私鑰cakey.pem及一張根證書cacert.pem,現在就可以用cacert.pem來給服務器證書或客戶證書籤名了。

我們規範一下CA證書的命名,把CA證書和密鑰重命名一下:

cp demoCA/private/cakey.pem ca.key

cp demoCA/cacert.pem ca.crt

ca.key是中間級證書私鑰,ca.crt是中間級證書。

 

2.       服務器證書

a)  生成服務器私鑰

openssl genrsa -des3 -out server.key 1024

輸入加密密碼,用128rsa算法生成密鑰,得到server.key文件。

 

b)  生成服務器證書請求(CSR

openssl req -new -key server.key -out server.csr

CSRCertificate Signing Request)是一個證書籤名請求,在申請證書之前,首先要在WEB服務器上生成CSR,並將其提交給CA認證中心,CA才能給您簽發SSL服務器證書。可以這樣認爲,CSR就是一個在您服務器上生成的證書。CSR主要包括以下內容:

Country Name (2 letter code) [AU]:CN

State or Province Name (full name) [Some-State]:Guangdong

Locality Name (eg, city) []:Shenzhen

Organization Name (eg, company) [Internet Widgits Pty Ltd]:xxx

Organizational Unit Name (eg, section) []:xxx

Common Name (eg, YOUR name) []:shenmiguo.com

Email Address []:[email protected]

 

Please enter the following ‘extra’ attributes

to be sent with your certificate request

A challenge password []:

An optional company name []:

Common Name填入主機名和CA一致。

 

c)  自己生成服務器證書

如果不使用CA證書籤名的話,用如下方式生成:

openssl req -x509 -days 1024 -key server.key -in server.csr > server.crt

用服務器密鑰和證書請求生成證書server.crt-days參數指明證書有效期,單位爲天。商業上來說,服務器證書是由通過第三方機構頒發的,該證書由第三方認證機構頒發的。

 

如果使用CA證書籤名,用openssl提供的工具CA.sh生成服務器證書:

mv server.csr newreq.pem

./CA.sh -sign

mv newcert.pem server.crt

 

簽名證書後,可通過如下命令可查看服務器證書的內容:

openssl x509 -noout -text -in server.crt

可通過如下命令驗證服務器證書:

openssl verify -CAfile ca.crt server.crt 

 

3.       客戶證書

客戶證書是可選的。如果有客戶證書,就是雙向認證HTTPS,否則就是單向認證HTTPS

a)  生成客戶私鑰

openssl genrsa -des3 -out client.key 1024

b)  生成客戶證書籤名請求

openssl req -new -key client.key -out client.csr

c)  生成客戶證書(使用CA證書籤名)

openssl ca -in client.csr -out client.crt

d)  證書轉換成瀏覽器認識的格式

openssl pkcs12 -export -clcerts -in client.crt -inkey client.key -out client.pfx

 

4.       證書列表

如果使用雙向認證,就會有三個私鑰和三個證書。分別是ca.key, ca.crt, server.key, server.crt, client.key, client.crt,以及給瀏覽器的client.pfx

如果使用有CA證書的單向認證,證書和私鑰就是ca.key, ca.crt, server.key, server.crt

如果使用無CA證書的單向認證,證書和私鑰就是server.key, server.crt

===================================================

基於ssl,一般的應用都是單向認證,如果應用場景要求對客戶來源做驗證也可以實現成雙向認證。

爲了便於更好的認識和理解 SSL 協議,這裏着重介紹 SSL 協議的握手協議。SSL 協議既用到了公鑰加密技術又用到了對稱加密技術,對稱加密技術雖然比公鑰加密技術的速度快,可是公鑰加密技術提供了更好的身份認證技術。SSL 的握手協議非常有效的讓客戶和服務器之間完成相互之間的身份認證,其主要過程如下:
  ① 客戶端的瀏覽器向服務器傳送客戶端 SSL 協議的版本號,加密算法的種類,產生的隨機數,以及其他服務器和客戶端之間通訊所需要的各種信息。
  ② 服務器向客戶端傳送 SSL 協議的版本號,加密算法的種類,隨機數以及其他相關信息,同時服務器還將向客戶端傳送自己的證書。
  ③ 客戶利用服務器傳過來的信息驗證服務器的合法性,服務器的合法性包括:證書是否過期,發行服務器證書的 CA 是否可靠,發行者證書的公鑰能否正確解開服務器證書的“發行者的數字簽名”,服務器證書上的域名是否和服務器的實際域名相匹配。如果合法性驗證沒有通過,通訊將斷開;如果合法性驗證通過,將繼續進行第四步。
  ④ 用戶端隨機產生一個用於後面通訊的“對稱密碼”,然後用服務器的公鑰(服務器的公鑰從步驟②中的服務器的證書中獲得)對其加密,然後將加密後的“預主密碼”傳給服務器。
  ⑤ 如果服務器要求客戶的身份認證(在握手過程中爲可選),用戶可以建立一個隨機數然後對其進行數據簽名,將這個含有簽名的隨機數和客戶自己的證書以及加密過的“預主密碼”一起傳給服務器。
  ⑥ 如果服務器要求客戶的身份認證,服務器必須檢驗客戶證書和簽名隨機數的合法性,具體的合法性驗證過程包括:客戶的證書使用日期是否有效,爲客戶提供證書的 CA 是否可靠,發行 CA 的公鑰能否正確解開客戶證書的發行 CA 的數字簽名,檢查客戶的證書是否在證書廢止列表(CRL)中。檢驗如果沒有通過,通訊立刻中斷;如果驗證通過,服務器將用自己的私鑰解開加密的“預主密碼”,然後執行一系列步驟來產生主通訊密碼(客戶端也將通過同樣的方法產生相同的主通訊密碼)。
  ⑦ 服務器和客戶端用相同的主密碼即“通話密碼”,一個對稱密鑰用於 SSL 協議的安全數據通訊的加解密通訊。同時在 SSL 通訊過程中還要完成數據通訊的完整性,防止數據通訊中的任何變化。
  ⑧ 客戶端向服務器端發出信息,指明後面的數據通訊將使用的步驟⑦中的主密碼爲對稱密鑰,同時通知服務器客戶端的握手過程結束。
  ⑨ 服務器向客戶端發出信息,指明後面的數據通訊將使用的步驟⑦中的主密碼爲對稱密鑰,同時通知客戶端服務器端的握手過程結束。
  ⑩ SSL 的握手部分結束,SSL 安全通道的數據通訊開始,客戶和服務器開始使用相同的對稱密鑰進行數據通訊,同時進行通訊完整性的檢驗。

  雙向認證 SSL 協議的具體過程
  ① 瀏覽器發送一個連接請求給安全服務器。
  ② 服務器將自己的證書,以及同證書相關的信息發送給客戶瀏覽器。
  ③ 客戶瀏覽器檢查服務器送過來的證書是否是由自己信賴的 CA 中心所簽發的。如果是,就繼續執行協議;如果不是,客戶瀏覽器就給客戶一個警告消息:警告客戶這個證書不是可以信賴的,詢問客戶是否需要繼續。
  ④ 接着客戶瀏覽器比較證書裏的消息,例如域名和公鑰,與服務器剛剛發送的相關消息是否一致,如果是一致的,客戶瀏覽器認可這個服務器的合法身份。
  ⑤ 服務器要求客戶發送客戶自己的證書。收到後,服務器驗證客戶的證書,如果沒有通過驗證,拒絕連接;如果通過驗證,服務器獲得用戶的公鑰。
  ⑥ 客戶瀏覽器告訴服務器自己所能夠支持的通訊對稱密碼方案。
  ⑦ 服務器從客戶發送過來的密碼方案中,選擇一種加密程度最高的密碼方案,用客戶的公鑰加過密後通知瀏覽器。
  ⑧ 瀏覽器針對這個密碼方案,選擇一個通話密鑰,接着用服務器的公鑰加過密後發送給服務器。
  ⑨ 服務器接收到瀏覽器送過來的消息,用自己的私鑰解密,獲得通話密鑰。
  ⑩ 服務器、瀏覽器接下來的通訊都是用對稱密碼方案,對稱密鑰是加過密的。
  上面所述的是雙向認證 SSL 協議的具體通訊過程,這種情況要求服務器和用戶雙方都有證書。單向認證 SSL 協議不需要客戶擁有 CA 證書,具體的過程相對於上面的步驟,只需將服務器端驗證客戶證書的過程去掉,以及在協商對稱密碼方案,對稱通話密鑰時,服務器發送給客戶的是沒有加過密的(這並不影響 SSL 過程的安全性)密碼方案。 這樣,雙方具體的通訊內容,就是加過密的數據,如果有第三方攻擊,獲得的只是加密的數據,第三方要獲得有用的信息,就需要對加密的數據進行解密,這時候的安全就依賴於密碼方案的安全。而幸運的是,目前所用的密碼方案,只要通訊密鑰長度足夠的長,就足夠的安全。這也是我們強調要求使用 128 位加密通訊的原因。

 一般web應用都是採用單向認證的,原因很簡單,用戶數目廣泛,且無需做在通訊層做用戶身份驗證,一般都在應用邏輯層來保證用戶的合法登入。

 但如果是企業應用對接,情況就不一樣,可能會要求對client(相對而言)做身份驗證。這時需要做雙向認證。

 用java簡單試了一下如何搭建一個https站點, tomcat 6 https 單向認證,網上google一下,例子很多,這裏就不貼出來了,然後瀏覽器測試。

 繼續瀏覽此網站,可以正式訪問。 服務器搭建,應該是沒問題了。 但是這個警告是怎麼回事? 還是應該再瞭解一下的。

 這個證書是自己做的,用jdk的工具keytool 很容易可以搞出一個(不懂請google), 瀏覽器很明顯不信任這個服務器發過來的證書(公鑰)。 這裏還需要了解一下,瀏覽器是如何信任一個證書的。

 1 瀏覽器 https: 訪問一個網站

 2 網站服務器會發給瀏覽器 一個證書

 3 瀏覽器驗證證書有效性:

    3.1 證書與訪問域名是否匹配,證書是否還在已經有效期內。

    3.2 證書的路徑。

          如圖:

         
         
          證書是否由 瀏覽器(客戶端) 所信任的機構認證。 如果在,則通過,否則給用戶自己選擇。

          自己折騰的證書沒給第三方認證,肯定彈warn, 於是乎出現了第一個圖。

         
         

有了以上的基礎知識,網上再找一下,自己寫一個簡單的java程序,要實現,https順利訪問(無warn)

easy, 把這個證書設置爲自己信任的就ok.

通過jdk的keytool 產生對應證書,並導入到truststore,生成一個文件(該文件存儲了信任的證書)。在java程序中指定truststore對應的文件。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章