JAVA 導入信任證書 (Keytool 的使用)

1. 問題背景

使用 ssl 連接時,遇到不信任的證書,應用程序一般都會拒絕連接。

瀏覽網站時,我們可以通過在瀏覽器的設置中導入證書,把證書加入到信任列表中。

而在 JAVA 直接進行 SSL 連接應用時,默認沒有一個界面來導入證書。JAVA 進行不信任的 ssl 連接時,會報如下異常:

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 的運行環境中導入信任證書。

2. 診斷方式

參照鏈接: https://confluence.atlassian.com/kb/unable-to-connect-to-ssl-services-due-to-pkix-path-building-failed-779355358.html

以上鍊接中提供了一種方式,用於診斷你的 Java 環境中是否包含了相應的信任證書。此方式可診斷 HTTPS, IMAPS, LDAPS 等。

  1. 下載 https://confluence.atlassian.com/kb/files/779355358/779355357/1/1441897666313/SSLPoke.class
  2. 運行如下命令,診斷連接是否可信。
$JAVA_HOME/bin/java SSLPoke jira.example.com 443

其中 java 是你要使用的 java 環境,後面是你要診斷的 url 和 port 。

如果連接成功,則出現如下結果:

$JAVA_HOME/bin/java SSLPoke jira.example.com 443
Successfully connected

而連接失敗時,則出現如下異常:

sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:387)
	at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)
	at sun.security.validator.Validator.validate(Validator.java:260)
	at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324)
	at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229)
	at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124)
	at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1351)
	at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:156)
	at sun.security.ssl.Handshaker.processLoop(Handshaker.java:925)
	at sun.security.ssl.Handshaker.process_record(Handshaker.java:860)
	at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1043)
	at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1343)
	at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:728)
	at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:123)
	at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:138)
	at SSLPoke.main(SSLPoke.java:31)
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:145)
	at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:131)
	at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
	at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382)
	... 15 more

此方式還能診斷 LDAPS 等 SSL 連接, 如 LDAPS 常用 636 端口:

$JAVA_HOME/bin/java SSLPoke ldap.example.com 636
Successfully connected

3. 解決方式

Java 使用了一種叫 keystore 的文件來存儲證書 (默認是位於 $JAVA_HOME/lib/security/cacerts ) 。

該文件使用 keytool 工具去管理 (該工具默認位於 $JAVA_HOME/bin/keytool )。

keytool 工具的使用不在這裏展開,網上有比較詳細的說明。這裏主要列舉幾個會用到的命令。

1). 列出 keystore 中的證書。

keytool -list

默認情況下,它會在你的 $HOME 目錄下產生一個空的 .keystore 文件。如要指定 Java 正在用的 keystore 文件,使用以下參數

keytool -list -keystore $JAVA_HOME/lib/security/cacerts

注意一下, keystore 文件都受 密碼 保護。生成新的 keystore 文件時,會要求你輸入一個新密碼;而當訪問一個已有的 keystore 文件時,會要求你驗證密碼。

$JAVA_HOME/lib/security/cacerts 的默認密碼爲 “changeit” !!!

$JAVA_HOME/lib/security/cacerts 的默認密碼爲 “changeit” !!!

$JAVA_HOME/lib/security/cacerts 的默認密碼爲 “changeit” !!!

重要的事情說三遍!!!

2). 導入證書。

keytool -import -alias <證書別名> -keystore $JAVA_HOME/jre/lib/security/cacerts -file your.crt

導入時會需要驗證密碼,默認密碼見上面。

4.附加內容:如何獲取一個網站的證書

參考鏈接: https://confluence.atlassian.com/kb/connecting-to-ssl-services-802171215.html

google.com 爲例。

Unix 方式

openssl s_client -connect google.com:443 < /dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > public.crt

Windows 方式

openssl s_client -connect google.com:443 < NUL | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > public.crt
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章