0x00 緒言
通過 java 執(zhí)行 https 請求時可能出現(xiàn)以下錯誤:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
這是因為 java 在執(zhí)行 SSL/TLS 通訊時使用特定的數(shù)據(jù)識別 Certificate Authorities(CA),如果你試圖發(fā)起的 SSL/TLS 連接使用不屬于這些根證書機(jī)構(gòu)所頒發(fā)的證書,就會拋出
SunCertPathBuilderException: unable to find valid certification path to requested target
因此,如果你使用自簽名證書,或者根證書機(jī)構(gòu)不在 JRE 默認(rèn)信任列表中,則需要向 JRE 導(dǎo)入根證書。
最近我們有個項目使用了沃通的免費 SSL 證書,因其根證書屬于 StartSSL 并不在 JRE 默認(rèn)信任列表中,因此簡單記錄下導(dǎo)入過程。
0x01 導(dǎo)入根證書到 JRE
首先,我們需要獲取根證書:
mkdir ~/tmp
cd ~/tmp
curl http://www.startssl.com/certs/ca.crt -O
curl http://www.startssl.com/certs/sub.class1.server.ca.crt -O
curl http://www.startssl.com/certs/sub.class2.server.ca.crt -O
curl http://www.startssl.com/certs/sub.class3.server.ca.crt -O
curl http://www.startssl.com/certs/sub.class4.server.ca.crt -O
然后,將證書導(dǎo)入到 JRE 信任列表:
sudo keytool -import -trustcacerts -keystore /Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre/lib/security/cacerts -storepass changeit -noprompt -alias startcom.ca -file ca.crt
sudo keytool -import -trustcacerts -keystore /Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre/lib/security/cacerts -storepass changeit -noprompt -alias startcom.ca.sub.class1 -file sub.class1.server.ca.crt
sudo keytool -import -trustcacerts -keystore /Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre/lib/security/cacerts -storepass changeit -noprompt -alias startcom.ca.sub.class2 -file sub.class2.server.ca.crt
sudo keytool -import -trustcacerts -keystore /Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre/lib/security/cacerts -storepass changeit -noprompt -alias startcom.ca.sub.class3 -file sub.class3.server.ca.crt
sudo keytool -import -trustcacerts -keystore /Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre/lib/security/cacerts -storepass changeit -noprompt -alias startcom.ca.sub.class4 -file sub.class4.server.ca.crt
別奇怪,"changeit" 只是個默認(rèn)密碼而已。
最后,驗證一下導(dǎo)入是否成功:
keytool -keystore "/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre/lib/security/cacerts" -storepass changeit -list | grep start
輸出:
startcom.ca, 2015-11-3, trustedCertEntry,
startcom.ca.sub.class4, 2015-11-3, trustedCertEntry,
startcom.ca.sub.class3, 2015-11-3, trustedCertEntry,
startcom.ca.sub.class2, 2015-11-3, trustedCertEntry,
startcom.ca.sub.class1, 2015-11-3, trustedCertEntry,
It's OK!