常見(jiàn)的https站點(diǎn)都是客戶端用服務(wù)端提供的證書(shū)驗(yàn)證服務(wù)端的簽名,確認(rèn)自己訪問(wèn)的站點(diǎn)不是偽造的。同樣的,服務(wù)端也可以添加客戶端提供的公鑰證書(shū),用來(lái)驗(yàn)證客戶端的身份。流程同上,客戶端用私鑰簽名后,服務(wù)端用客戶端的公鑰證書(shū)驗(yàn)簽。
下面我用tomcat-8.5.64來(lái)演示一下如何配置基于tomcat的自簽名證書(shū)的https雙向認(rèn)證。
生成服務(wù)器端和客戶端的密鑰對(duì)
首先生成兩個(gè)密鑰對(duì),一個(gè)給服務(wù)端使用(也就是tomcat),一個(gè)給客戶端使用(也就是瀏覽器端)。我們用JDK提供的keytool工具來(lái)生成密鑰對(duì)。
>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"
用同樣的方式再生成客戶端的密鑰對(duì)。
>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"
從客戶端的密鑰庫(kù)中導(dǎo)出公鑰證書(shū),把這個(gè)證書(shū)提供給服務(wù)端,服務(wù)端需要將它添加到自己的信任證書(shū)庫(kù)中。
>keytool -exportcert -alias client -file client.cert -keystore client-key.p12 -storepass 123456
執(zhí)行上一條命令得到客戶端證書(shū)文件client.cert。為了方便tomcat的配置,直接將這個(gè)證書(shū)導(dǎo)入一個(gè)空的密鑰庫(kù)。
>keytool -importcert -alias client -file client.cert -keystore server-trust.p12 -storetype PKCS12 -storepass 123456
配置tomcat
將服務(wù)端密鑰庫(kù)和信任密鑰庫(kù)考到tomcat的conf目錄中,這個(gè)不是必須的,復(fù)制過(guò)去只是為了方便配置和管理,也可以在tomcat中配置這兩個(gè)密鑰庫(kù)的絕對(duì)路徑。
tomcat默認(rèn)是沒(méi)有開(kāi)啟https的,我們?cè)赾onf目錄里面找到server.xml并用文本編輯器打開(kāi)它。找到被注釋掉的SSL/TLS HTTP/1.1 Connector,如下圖所示:

取消這個(gè)connector的注釋。將服務(wù)端密鑰庫(kù)配置在Certificate節(jié)點(diǎn)中。
<Certificate certificateKeystoreFile="conf/tomcat-key.p12"
certificateKeystorePassword="123456"
type="RSA" />
certificateKeystoreFile配置的就是密鑰庫(kù)的位置,由于我們把它拷貝到了conf目錄中,所以我們只需配置它的相對(duì)路徑就可以了。certificateKeystorePassword指定密鑰庫(kù)的密碼。type指定密鑰庫(kù)的類型。我們生成的時(shí)候指定的類型是RSA,所以這里也配置為RSA就可以了。這樣配置好以后,單向的https就成功了,我們可以啟動(dòng)tomcat試一試。在瀏覽器中輸入https://localhost:8443。

看到的結(jié)果如上圖所示,因?yàn)槲覀兪褂玫氖亲院灻拿荑€庫(kù),所以不受瀏覽器的信任,我們點(diǎn)擊“高級(jí)”:

然后點(diǎn)擊“繼續(xù)前往localhost(不安全)”:

打開(kāi)了tomcat的管理頁(yè)面。左上角有個(gè)“不安全”的提示,提示這個(gè)的原因同上,我們的服務(wù)端密鑰庫(kù)是自簽名的,響應(yīng)給瀏覽器的證書(shū)也是自簽名的,不受瀏覽器信任。
接著我們繼續(xù)配置雙向的https。單向是服務(wù)端向客戶端提供自己的證書(shū),客戶端用此證書(shū)驗(yàn)證服務(wù)端的身份,雙向的話就是還需要客戶端向服務(wù)端提供證書(shū),服務(wù)端用這個(gè)證書(shū)來(lái)驗(yàn)證客戶端的身份。服務(wù)端這邊的話就只需要把我們剛才生成的第三個(gè)密鑰庫(kù)(導(dǎo)入了客戶端證書(shū)的那個(gè))配置到tomcat中。這個(gè)需要配置到SSLHostConfig節(jié)點(diǎn)上。完整的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就是配置的客戶端證書(shū)所在的密鑰庫(kù),truststorePassword配置的是該密鑰庫(kù)的密碼,而certificateVerification配置為"required"表示必須進(jìn)行客戶端身份驗(yàn)證。配置完畢后我們重新啟動(dòng)tomcat,然后嘗試訪問(wèn)它。得到如下圖所示的頁(yè)面:

這是因?yàn)榭蛻舳嗣荑€庫(kù)還沒(méi)有配置導(dǎo)致的??蛻舳擞妹荑€庫(kù)中的私鑰簽名后,服務(wù)端才能用我們剛才配置的受信任密鑰庫(kù)中的客戶端證書(shū)進(jìn)行驗(yàn)證。我使用的是chrome瀏覽器,打開(kāi)瀏覽器的“設(shè)置”頁(yè)面,點(diǎn)擊左側(cè)的“隱私設(shè)置和安全性”菜單,

然后點(diǎn)擊上圖紅框中的“安全”,進(jìn)入如下圖所示頁(yè)面:

往下滾動(dòng)頁(yè)面,找到“管理證書(shū)”:

點(diǎn)擊右側(cè)紅框中的箭頭,彈出如下圖所示的windows系統(tǒng)證書(shū)管理界面:

然后點(diǎn)擊“導(dǎo)入”按鈕,進(jìn)入證書(shū)導(dǎo)入向?qū)В?br>

點(diǎn)擊“下一步”,進(jìn)入如下圖所示界面:

點(diǎn)擊“瀏覽”,選擇我們剛才生成的客戶端密鑰庫(kù)文件:

然后點(diǎn)擊“下一步”:

輸入密鑰庫(kù)的密碼,并且勾選“啟用強(qiáng)私鑰保護(hù)”復(fù)選框,點(diǎn)擊“下一步”:

默認(rèn)證書(shū)存儲(chǔ)的位置是個(gè)人,我們不用改變它,直接點(diǎn)擊“下一步”:

最后點(diǎn)擊“完成”:

會(huì)彈出如上圖所示的一個(gè)提示框,我們不管它,直接點(diǎn)擊“確定”,然后會(huì)彈出導(dǎo)入成功的提示框,表示客戶端的密鑰庫(kù)已經(jīng)配置完畢,這時(shí)我們?cè)俅螄L試訪問(wèn)頁(yè)面:

瀏覽器會(huì)彈出一個(gè)如上圖所示的提示框,我們選中剛才配置的密鑰庫(kù),然后點(diǎn)擊確定,此時(shí)還會(huì)彈出一個(gè)提示框:

點(diǎn)擊“允許”,完成后會(huì)看到tomcat的管理頁(yè)面已經(jīng)正常打開(kāi)了。
至此,針對(duì)tomcat的https雙向認(rèn)證配置就完成了。