常見的https站點都是客戶端用服務端提供的證書驗證服務端的簽名,確認自己訪問的站點不是偽造的。同樣的,服務端也可以添加客戶端提供的公鑰證書,用來驗證客戶端的身份。流程同上,客戶端用私鑰簽名后,服務端用客戶端的公鑰證書驗簽。
下面我用tomcat-8.5.64來演示一下如何配置基于tomcat的自簽名證書的https雙向認證。
生成服務器端和客戶端的密鑰對
首先生成兩個密鑰對,一個給服務端使用(也就是tomcat),一個給客戶端使用(也就是瀏覽器端)。我們用JDK提供的keytool工具來生成密鑰對。
>keytool -genkeypair -alias server -keyalg RSA -validity 365 -storetype PKCS12 -keystore tomcat-key.p12 -storepass 123456 -dname "CN=tomcat-site.com,OU=tomcat,O=mytomcat,L=chengdu,S=sichuan,C=CN"
用同樣的方式再生成客戶端的密鑰對。
>keytool -genkeypair -alias client -keyalg RSA -validity 365 -storetype PKCS12 -keystore client-key.p12 -storepass 123456 -dname "CN=client-site.com,OU=my,O=myclient,L=chengdu,S=sichuan,C=CN"
從客戶端的密鑰庫中導出公鑰證書,把這個證書提供給服務端,服務端需要將它添加到自己的信任證書庫中。
>keytool -exportcert -alias client -file client.cert -keystore client-key.p12 -storepass 123456
執行上一條命令得到客戶端證書文件client.cert。為了方便tomcat的配置,直接將這個證書導入一個空的密鑰庫。
>keytool -importcert -alias client -file client.cert -keystore server-trust.p12 -storetype PKCS12 -storepass 123456
配置tomcat
將服務端密鑰庫和信任密鑰庫考到tomcat的conf目錄中,這個不是必須的,復制過去只是為了方便配置和管理,也可以在tomcat中配置這兩個密鑰庫的絕對路徑。
tomcat默認是沒有開啟https的,我們在conf目錄里面找到server.xml并用文本編輯器打開它。找到被注釋掉的SSL/TLS HTTP/1.1 Connector,如下圖所示:
取消這個connector的注釋。將服務端密鑰庫配置在Certificate節點中。
<Certificate certificateKeystoreFile="conf/tomcat-key.p12"
certificateKeystorePassword="123456"
type="RSA" />
certificateKeystoreFile配置的就是密鑰庫的位置,由于我們把它拷貝到了conf目錄中,所以我們只需配置它的相對路徑就可以了。certificateKeystorePassword指定密鑰庫的密碼。type指定密鑰庫的類型。我們生成的時候指定的類型是RSA,所以這里也配置為RSA就可以了。這樣配置好以后,單向的https就成功了,我們可以啟動tomcat試一試。在瀏覽器中輸入https://localhost:8443
。
看到的結果如上圖所示,因為我們使用的是自簽名的密鑰庫,所以不受瀏覽器的信任,我們點擊“高級”:
然后點擊“繼續前往localhost(不安全)”:
打開了tomcat的管理頁面。左上角有個“不安全”的提示,提示這個的原因同上,我們的服務端密鑰庫是自簽名的,響應給瀏覽器的證書也是自簽名的,不受瀏覽器信任。
接著我們繼續配置雙向的https。單向是服務端向客戶端提供自己的證書,客戶端用此證書驗證服務端的身份,雙向的話就是還需要客戶端向服務端提供證書,服務端用這個證書來驗證客戶端的身份。服務端這邊的話就只需要把我們剛才生成的第三個密鑰庫(導入了客戶端證書的那個)配置到tomcat中。這個需要配置到SSLHostConfig節點上。完整的connector的配置如下:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true">
<SSLHostConfig truststoreFile="conf/server-trust.p12" truststorePassword="123456" certificateVerification="required">
<Certificate certificateKeystoreFile="conf/tomcat-key.p12"
certificateKeystorePassword="123456"
type="RSA" />
</SSLHostConfig>
</Connector>
truststoreFile就是配置的客戶端證書所在的密鑰庫,truststorePassword配置的是該密鑰庫的密碼,而certificateVerification配置為"required"表示必須進行客戶端身份驗證。配置完畢后我們重新啟動tomcat,然后嘗試訪問它。得到如下圖所示的頁面:
這是因為客戶端密鑰庫還沒有配置導致的??蛻舳擞妹荑€庫中的私鑰簽名后,服務端才能用我們剛才配置的受信任密鑰庫中的客戶端證書進行驗證。我使用的是chrome瀏覽器,打開瀏覽器的“設置”頁面,點擊左側的“隱私設置和安全性”菜單,
然后點擊上圖紅框中的“安全”,進入如下圖所示頁面:
往下滾動頁面,找到“管理證書”:
點擊右側紅框中的箭頭,彈出如下圖所示的windows系統證書管理界面:
然后點擊“導入”按鈕,進入證書導入向導:
點擊“下一步”,進入如下圖所示界面:
點擊“瀏覽”,選擇我們剛才生成的客戶端密鑰庫文件:
然后點擊“下一步”:
輸入密鑰庫的密碼,并且勾選“啟用強私鑰保護”復選框,點擊“下一步”:
默認證書存儲的位置是個人,我們不用改變它,直接點擊“下一步”:
最后點擊“完成”:
會彈出如上圖所示的一個提示框,我們不管它,直接點擊“確定”,然后會彈出導入成功的提示框,表示客戶端的密鑰庫已經配置完畢,這時我們再次嘗試訪問頁面:
瀏覽器會彈出一個如上圖所示的提示框,我們選中剛才配置的密鑰庫,然后點擊確定,此時還會彈出一個提示框:
點擊“允許”,完成后會看到tomcat的管理頁面已經正常打開了。
至此,針對tomcat的https雙向認證配置就完成了。