搭建私有CA並基於OpenSSL實現雙向身份認證

0x00 前言

互聯網上的Web應用因爲用戶數目普遍,都是採用單向身份認證的,只須要客戶端驗證服務端的身份。但若是是企業內部的應用對接,客戶端數量有限,可能就會要求對客戶端也作身份驗證,這時就須要一個雙向認證方案。本文經過搭建私有CA,利用OpenSSL工具,實現服務端與客戶端的雙向身份認證。安全協議採用HTTPS,這裏用到的HTTPS除了可以進行身份認證之外,還能保證通訊的保密性和完整性。html

0x01 組建方案

組建方案以下圖所示:java

  • 整個方案包括一個私有CA、一個服務端、一個客戶端,用於驗證HTTPS雙向身份認證的可行性。
  • 服務端的系統環境爲CentOS7,Web服務器採用Tomcat7。客戶端的系統環境爲Windows,瀏覽器採用Firefox。
  • 由私有CA負責生成全部的私鑰、證書等文件,並經過線下安全途徑分發到服務端和客戶端。
  • 其中,CA的私鑰最爲重要需加密後離線保管;服務端持有CA證書、服務器私鑰、服務器證書3個文件;客戶端持有CA證書、客戶端私鑰、客戶端證書3個文件。
  • 客戶端與服務端經過HTTPS安全協議進行雙向身份認證、加密傳輸。另外,須要注意的是,HTTPS實現的是傳輸層的身份認證,不含應用層鑑權功能。

0x02 私有CA的設置

安裝與配置OpenSSL

安裝OpenSSLgit

yum install openssl
yum install openssl-devel

OpenSSL默認安裝完後,另外須要建立如下幾個文件: github

touch /etc/pki/CA/index.txt       #index文件用於記錄已經簽發的證書
touch /etc/pki/CA/serial
echo 00 > /etc/pki/CA/serial      #serial文件用於存放證書的序列號,自動遞增

完成該實驗後index.txt中的信息爲下面兩條,即簽發了兩個證書分別是服務端證書和客戶端證書web

由於,服務器證書請求文件的國家、省、市要和CA證書一致,這個在openssl.cnf默認配置中指定了。
能夠經過修改/etc/pki/tls/openssl.cnf文件,調整爲非強制一致。
將下面的幾個match 修改成 optionalapache

# For the CA policy  
[ policy_match ]
countryName             = match
stateOrProvinceName     = match
organizationName        = match

自籤CA證書

生成根證書私鑰 cakey.pem

openssl genrsa  -des3 -out cakey.pem  2048 這一步須要輸入密碼,密碼用於加密私鑰,使私鑰非明文存於磁盤  

生成根證書籤發申請文件 ca.csr

openssl req -new -key cakey.pem -out ca.csr -subj "/C=CN/O=CAorganization/CN=myCA"

自簽發根證書 cacert.pem

openssl x509 -req -days 3650 -sha256 -extensions v3_ca -signkey cakey.pem -in ca.csr -out  cacert.pem  

服務端的私鑰與證書

生成服務端私鑰 serverkey.pem

openssl genrsa -out serverkey.pem 2048  

生成證書請求文件 server.csr

openssl req -new \
-sha256 \
-key serverkey.pem \
-subj "/C=CN/ST=myprovince/L=mycity/O=myorganization/OU=mygroup/CN=myserver.test.com" \
-reqexts SAN \
-config <(cat /etc/pki/tls/openssl.cnf \
    <(printf "[SAN]\nsubjectAltName=DNS:myserver.test.com,DNS:myserver2.test.com")) \
-out server.csr  

使用根證書籤發服務端證書 servercert.pem

openssl ca -in server.csr \
-md sha256 \
-days 3650 \
-keyfile cakey.pem \
-cert cacert.pem \
-extensions SAN \
-config <(cat /etc/pki/tls/openssl.cnf \
    <(printf "[SAN]\nsubjectAltName=DNS:myserver.test.com,DNS:myserver2.test.com")) \
-out servercert.pem  

客戶端的私鑰與證書

生成客戶端私鑰 clientkey.pem

openssl genrsa -out  clientkey.pem 2048  

生成證書請求文件 client.csr 

openssl req -new \
-sha256 \
-key clientkey.pem \
-subj "/C=CN/ST=myprovince/L=mycity/O=myorganization/OU=mygroup/CN=myclient.test.com" \
-reqexts SAN \
-config <(cat /etc/pki/tls/openssl.cnf \
    <(printf "[SAN]\nsubjectAltName=DNS:myclient.test.com,DNS:myclient2.test.com")) \
-out client.csr  

使用根證書籤發客戶端證書 clientcert.pem

openssl ca -in client.csr \
-md sha256 \
-days 3650 \
-keyfile cakey.pem \
-cert cacert.pem \
-extensions SAN \
-config <(cat /etc/pki/tls/openssl.cnf \
<(printf "[SAN]\nsubjectAltName=DNS:myclient.test.com,DNS:myclient2.test.com")) \
-out clientcert.pem  

0x03 服務器端的設置

安裝Java、Tomcat、建立JKS存放目錄

Java、Tomcat安裝完後 http://www.javashuo.com/article/p-gvfvhdlm-ds.html瀏覽器

建立存放JKS文件的目錄,服務端的Tomcat將用到的JKS格式的私鑰和證書tomcat

mkdir -p  /data/live  #此目錄以後用於存放JKS文件

把服務端私鑰和證書製做成JKS文件

#獲得 fullchain_and_key.p12
openssl pkcs12 -export -in  servercert.pem -inkey serverkey.pem  -out fullchain_and_key.p12 -name ssl

這一步須要輸入密碼,假設此處輸入密碼爲: mypassword安全

#獲得ssl.jks
keytool -importkeystore -deststorepass myJKSpassasdf -destkeypass myJKSpassasdf -destkeystore ssl.jks -srckeystore fullchain_and_key.p12 -srcstoretype PKCS12 -srcstorepass mypassword -alias ssl

#移位文件到/data/live
mv  ssl.jks  /data/live

把信任根證書製做成JKS文件

#獲得ssl2.jks
keytool -import -alias cacert -file  cacert.pem  -keystore ssl2.jks  -deststorepass myJKSpassasdf2  -destkeypass myJKSpassasdf2

#移位文件到/data/live
mv  ssl2.jks  /data/live

配置Tomcat

修改Tomcat的server.xml,配置HTTPS功能

 <Connector port="443" protocol="org.apache.coyote.http11.Http11Protocol"
           URIEncoding="UTF-8"  maxThreads="500" SSLEnabled="true" scheme="https" secure="true" clientAuth="true" sslProtocol="TLS"  
           keystoreFile="/data/live/ssl.jks" keystorePass="myJKSpassasdf" 
           truststoreFile="/data/live/ssl2.jks" truststorePass="myJKSpassasdf2"                
sslEnabledProtocols="TLSv1,TLSv1.1,TLSv1.2,SSLv2Hello"
ciphers="TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,   
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,  
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,  
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,  
TLS_ECDHE_RSA_WITH_RC4_128_SHA,  
TLS_RSA_WITH_AES_128_CBC_SHA256,  
TLS_RSA_WITH_AES_128_CBC_SHA,  
TLS_RSA_WITH_AES_256_CBC_SHA256,  
TLS_RSA_WITH_AES_256_CBC_SHA,  
SSL_RSA_WITH_RC4_128_SHA" />

一些參數說明:服務器

  • port該設置爲HTTPS端口號。
  • 若是clientAuth該設置爲「false」,則爲單向SSL驗證,不須要驗證客戶端證書。
  • 若是clientAuth設置爲「true」,表示強制雙向SSL驗證。
  • 若是clientAuth設置爲「want」,則表示能夠驗證客戶端證書,但若是客戶端沒有有效證書,也不強制驗證。
  • keystore就是用來存服務端自身的私鑰和證書。
  • truststore就是用來存根證書文件的。

 

在服務端強制HTTP訪問跳轉爲HTTPS

在server.xml文件,將redirectPort的8443端口,一概改成443(由於咱們以前已經設置了443端口做爲HTTPS端口)
在web.xml文件,插入這樣一段:

<login-config>  
    <!-- Authorization setting for SSL -->  
    <auth-method>CLIENT-CERT</auth-method>  
    <realm-name>Client Cert Users-only Area</realm-name>  
</login-config>  
<security-constraint>  
<!-- Authorization setting for SSL -->  
    <web-resource-collection >  
        <web-resource-name >SSL</web-resource-name>  
        <url-pattern>/*</url-pattern>  
    </web-resource-collection>  
    <user-data-constraint>  
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>  
    </user-data-constraint>  
</security-constraint> 

重啓tomcat生效

#關閉
cd /usr/local/tomcat/tomcat8/bin ./shutdown.sh
#查看是否關閉
ps -ef|grep java

此信息說明還沒關

#若是關不了,使用kill命令,直接殺死Tomcat進程
kill -9 12265

此信息說明關了

#啓動Tomcat
./startup.sh

查看tomcat日誌

0x04 客戶端的設置

修改客戶端hosts文件

hosts中加入一行 192.168.91.166  myserver.test.com
其中,假設192.168.91.166 是服務端的IP,根據實際狀況改寫。
注意:這裏hosts文件做用是代替DNS域名解析,僅爲測試使用。

客戶端瀏覽器導入CA根證書

Firefox瀏覽器導入cacert.pem文件 即CA根證書

客戶端瀏覽器導入本身的私鑰和證書

X509格式轉化爲pkcs12格式的文件

openssl pkcs12 -export -in  clientcert.pem -inkey clientkey.pem    -out  client.p12 -name client_ssl  

這一步須要輸入密碼,假設此處輸入密碼爲: mypassword

將client.p12導入到瀏覽器

0x05 雙向身份驗證與效果

瀏覽器打開URL: https://myserver.test.com
選擇客戶端證書

 

 成功打開網站

 

該實驗主要根據如下博客實現 

https://gamedun.github.io/-----https://runner-china.github.io/blog/2018/07/10/ca

其餘參考

https://blog.csdn.net/cuofucsdn/article/details/78851673

https://blog.csdn.net/Ningdaxing1994/article/details/78790493

http://www.javashuo.com/article/p-kcbjfajg-dh.html (該博文包含單向驗證和雙向驗證)

相關文章
相關標籤/搜索