在上述的文章后了解到原理之后,我們這篇文章來進行CA的搭建。
OPEN SSL 環境搭建
在基礎原理中我們提到了兩種認證服務,單項認證服務和雙向認證服務,我們就以雙向認證服務舉例說明。
OpenSSL是一個開放源代碼軟件包,實現了SSL以及相關加密技術,是最常用的證書管理工具,OpenSSL功能遠勝於KeyTool,可用於根證書(KeyTool不含有,因此KeyTool沒有辦法作為CA)、服務器證書、客戶證書的管理。
在OpenSSL官網下載:http:www.openssl.org/source/下載最新的源碼,官網還提供了windows版的二進制發行版地址:http://www.slproweb.com/products/Win32OpenSSL.html
1、 准備工作
選擇適合自己操作系統的版本進行下載后,安裝操作與普通軟件一樣,沒有什么區別
設置環境變量:

打開配置文件openssl.cfg(%OpenSSL_Home%\bin\openssl.cfg),找到配置[CA_default]:

上述變量dir,它指向的是CA工作目錄,可以對其進行修改
2、 創建bat文件
整個bat文件的創建過程我們可以把它想象成這樣一種場景:
高考結束,教育局來頒發畢業證書給各個學校,各個學校在把證書發給學生,具體步驟如下:
1) 教育局先有空白證書了
2) 教育局又有自己的公章
3) 讓各個學校可以擁有畢業證發放申請
4) 對空白的畢業證蓋上了教育局的公章,並可以交給已經申請的學校
5) 申請的學校拿到了蓋有教育局的畢業證后,准備對其蓋上自己的公章
6) 學校在教育局已經蓋上教育局公章的畢業證上又蓋上了自己學校的公章
7) 准備把畢業證發給學校申請畢業的學生們
8) 申請畢業的學生拿取自己的學生證和身份證准備領取畢業證
9) 來到學校教務處,填寫單據申請學校發放畢業證
10) 教育局已經轉交學校來發放畢業證,此時學校把畢業證發放給申請學生
11) 學生認為蓋有教育局的公章和學校的公章的畢業證是有效的
上述步驟,都可以在下面的bat文件中找到相應的地方:
- //構建ca子目錄(證書創建時,用到下述目錄,最終在certs目錄中獲得證書文件)
- echo 構建已發型證書存放目錄 certs
- mkdir certs
- echo 構建新證書存放目錄 newcerts
- mkdir newcerts
- echo 構建私鑰存放目錄 private
- mkdir private
- echo 構建證書吊銷列表存放目錄 crl
- mkdir cr1
- //構建相關文件,完成后可以進行證書的構建和簽發工作
- echo 構建索引文件 index.txt
- echo 0>index.txt
- echo 構建序列號文件 serial
- echo 01>serial
- //構建根證書
- echo 構建隨機數 private/.rand
- openssl rand -out private/.rand 1000
- //構建根證書私鑰
- echo 構建根證書私鑰 private/ca.key.pem
- openssl genrsa -aes256 -out private/ca.key.pem 2048
- //完成密鑰構建操作后,需要生成根證書簽發申請文件ca.csr
- //生成根證書簽發申請
- echo 生成根證書簽發申請 private/ca.csr
- openssl req -new -key private/ca.key.pem -out private/ca.csr -subj "/C=CN/ST=HUBEI/L=WUHAN/O=YALE/OU=YALE/CN=*.qiujinyong.org"
- //執行完后此處又要輸入根證書密碼
- //得到根證書簽發申請文件后,可以將其發送給CA機構簽發,也可以自行簽發根證書
- echo 簽發根證書 private/ca.cer
- openssl x509 -req -days 1000 -sha1 -extensions v3_ca -signkey private/ca.key.pem -in private/ca.csr -out certs/ca.cer
- //執行完后此處又要輸入根證書密碼
- echo 根證書轉換 private/ca.p12
- openssl pkcs12 -export -cacerts -inkey private/ca.key.pem -in certs/ca.cer -out certs/ca.p12
- //執行完后此處又要輸入根證書密碼
- //構建服務器證書
- echo 構建服務器私鑰 private/server.key.pem
- openssl genrsa -aes256 -out private/server.key.pem 2048
- //服務器證書簽發申請
- echo 生成服務器證書簽發申請 private/server.csr
- openssl req -new -key private/server.key.pem -out private/server.csr -subj "/C=CN/ST=HUBEI/L=WUHAN/O=YALE/OU=YALE/CN=www.qiujinyong.com"
- //執行完后此處又要輸入根證書密碼
- //根證書簽發服務器證書
- echo 簽發服務器證書 private/server.cer
- openssl x509 -req -days 3650 -sha1 -extensions v3_req -CA certs/ca.cer -CAkey private/ca.key.pem -CAserial ca.srl -CAcreateserial -in private/server.csr -out certs/server.cer
- //執行完后此處又要輸入根證書密碼
- //將OpenSSL產生的數字證書轉換為PKCS#12編碼格式
- echo 服務器證書轉換 private/server.p12
- openssl pkcs12 -export -clcerts -inkey private/server.key.pem -in certs/server.cer -out certs/server.p12
- //執行完后此處又要輸入根證書密碼
- //構建客戶證書
- echo 產生客戶私鑰 private/client.key.pem
- openssl genrsa -aes256 -out private/client.key.pem 2048
- //執行完后此處又要輸入根證書密碼
- //產生客戶證書簽發申請
- echo 生成客戶證書簽發申請 client.csr
- openssl req -new -key private/client.key.pem -out private/client.csr -subj "/C=CN/ST=HUBEI/L=WUHAN/O=YALE/OU=YALE/CN=qiujinyong"
- //執行完后此處又要輸入根證書密碼
- //根證書簽發客戶證書
- echo 簽發客戶證書 certs/client.cer
- openssl x509 -req -days 3650 -sha1 -extensions v3_req -CA certs/ca.cer -CAkey private/ca.key.pem -CAserial ca.srl -CAcreateserial -in private/client.csr -out certs/client.cer
- //執行完后此處又要輸入根證書密碼
- //將獲得客戶證書轉換JAVA語言可以識別的PKCS#12編碼格式
- echo 客戶證書轉換 certs/client.p12
- openssl pkcs12 -export -inkey private/client.key.pem -in certs/client.cer -out certs/client.p12
- //完成了雙向認證的所需的全部證書
3、 文件生成
通過上述語句我們生成了以下幾個“一級”文件以及文件夾:

Certs文件夾下又生成了:

Private文件夾下又生成了:

4、 證書導入
我們使用ca.p12、server.p12、client.p12個人信息交換文件構建雙向認證,在驗證操作之前,我們先導入ca.p12、client.p12文件
ca.p12文件是ca根證書的個人信息交換文件:
雙擊”ca.p12”或者點擊在瀏覽器"工具"->"internet選項"->"內容"中的"證書"->"導入"

點擊“下一步”后,“瀏覽”按鈕時,指定個人信息交換文件格式(*.p12;*.pfx), 選擇“ca.p12的所在位置”:


輸入私鑰的密碼:

選擇“將所有的證書放入下列存儲”:

點擊“瀏覽”,選擇“受信任的根證書頒發機構”:

點擊“下一步”,然后點擊“完成”
導入”client.p12”文件:
導入clinet.p12文件的方式和ca.p12文件方式基本相似,只是在證書存儲時,選擇“個人”:

5、 服務器配置
將”ca.p12”、”server.p12”文件復制到tomcat的conf目錄下:

同時,需要在windows系統下通過ie導入ca.p12和client.p12文件:


我們在tomcat的server.xml文件中配置雙向認證:
- <Connector port="443" maxHttpHeaderSize="8192"
- maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
- sslProtocol="TLS" keystoreFile="conf/server.p12"
- keystorePass="123456" keystoreType="PKCS12"
- truststoreFile="conf/ca.p12" acceptCount="100" scheme="https" secure="true"
- sslEnabled="true" clientAuth="true" truststorePass="123456" truststoreType="PKCS12"/>
這里的密鑰庫文件參數keystoreFile指向server.p12文件,密鑰庫密碼參數keystorePass值為”123456”,密鑰庫類型參數keystoreType值為”PKCS12”,因為雙向認證服務區分信任庫文件和密鑰庫文件,此時,server.p12文件將作為密鑰庫文件,而ca.p12文件則作為信任庫文件,因此,信任庫文件參數truststoreFile指向ca.p12文件,信任庫密碼參數truststorePass值為”123456”,信任庫類型參數truststoreType值為“pkcs12”,clientAuth的值為”true”,這是打開雙向認證的關鍵一步,port默認為8443,現在修改為443,這樣就省去我們在地址欄中輸入端口號。
效果展現
輸入我們證書綁定的網站,https打頭:

查看給該網站頒發的證書的屬性:

點擊授予權限:

如果我們是自己創建的根證書沒有通過CA驗證的話,那么會在地址欄中看到相關信息,如下圖:

點擊繼續瀏覽, 雖然我們連接的是本地服務器,但仍然會感到有些延時,這是因為瀏覽器訪問CA機構驗證該證書,並初始化加密/解密等信息:
上述我們看到“證書錯誤”,就是因為我們的根證書並沒有得到CA的認證
我們如果加上驗證的代碼后:
- for(Enumeration en = request.getAttributeNames();
- en.hasMoreElements();){
- String name = (String)en.nextElement();
- out.println(name);
- out.println(" = " + request.getAttribute(name));
- out.println();
- }
可以看到如下結果:

上述有些相關屬性解釋:
javax.servlet.request.ssl_session:當前SSL/TLS協議的會話ID
java.servlet.request.key_size:當前加密算法所使用的密鑰長度
javax.servlet.request.cipher_suite:當前SSL /TLS協議所使用的加密套件(比如上述:使用的TLS協議,RSA的非對稱加密算法,AES的對稱加密算法,同時是128的,SHA的消息摘要算法,CBC的工作模式,,,一般使用非對稱加密算法對數據進行加密/解密操作的效率相當低,而使用對稱加密算法進行加密/解密的效率相當高,合理的解決辦法是使用非對稱加密算法傳遞對稱加密算法的密鑰,使用對稱加密算法對數據加密)
javax.servlet.request.X509Certificate:指向客戶證書列表

