web-dev-qa-db-ja.com

JavaアプリケーションでPKIXパスの構築に失敗しました

Windows 2000からWindows 2008 R2 Serverにアプリケーションを移動した後、ほぼ1週間、アプリケーションを実行するのに苦労しています。

手順:

  1. インストール済みJava JDK 1.7.0_25
  2. システム環境変数Java_HOMEC:\Progra~1\Java\jdk1.7.0_25\に設定します
  3. keytoolを使用して証明書をcacertsにインポートしました
  4. 証明書が-listkeytoolに存在することを確認しました。

私はInstallCertステップ3を繰り返してみて、何かを台無しにしないようにしました。

上記の方法は私の問題を解決しなかったので、プログラムでそれをしようとしました:

System.setProperty("javax.net.ssl.trustStore",
"C:/Progra~1/Java/jdk1.7.0_25/jre/lib/security/cacerts");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");

まだ運がありません。私は立ち往生しており、ここからどの方向に進むべきかよくわかりません。

スタックトレース:

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
    at Sun.security.ssl.Alerts.getSSLException(Alerts.Java:192)
    at Sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.Java:1886)
    at Sun.security.ssl.Handshaker.fatalSE(Handshaker.Java:276)
    at Sun.security.ssl.Handshaker.fatalSE(Handshaker.Java:270)
    at Sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.Java:1341)
    at Sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.Java:153)
    at Sun.security.ssl.Handshaker.processLoop(Handshaker.Java:868)
    at Sun.security.ssl.Handshaker.process_record(Handshaker.Java:804)
    at Sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.Java:1016)
    at Sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.Java:1312)
    at Sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.Java:1339)
    at Sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.Java:1323)
    at Sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.Java:515)
    at Sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.Java:185)
    at Sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.Java:153)
    at util.SMS.send(SMS.Java:93)
    at domain.ActivationSMSSenderMain.sendActivationMessagesToCustomers(ActivationSMSSenderMain.Java:80)
    at domain.ActivationSMSSenderMain.<init>(ActivationSMSSenderMain.Java:44)
    at domain.ActivationSMSSenderMain.main(ActivationSMSSenderMain.Java:341)
Caused by: 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:385)
    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:326)
    at Sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.Java:231)
    at Sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.Java:126)
    at Sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.Java:1323)
    ... 14 more
Caused by: Sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at Sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.Java:196)
    at Java.security.cert.CertPathBuilder.build(CertPathBuilder.Java:268)
    at Sun.security.validator.PKIXValidator.doBuild(PKIXValidator.Java:380)
    ... 20 more

更新:

System.out.println(System.getProperty("javax.net.ssl.trustStore"));System.out.println(System.getProperty("javax.net.ssl.keyStore"));の両方

nullを返します。

35
JavaCake

原因と解決策の両方がかなり単純であることが判明した同様の問題に遭遇しました:

主な原因:keytoolを使用して適切な証明書をインポートしませんでした

注:ルートCA(または独自の自己署名)証明書のみをインポートします

注:中間の非証明書チェーンルート証明書をインポートしないでください

imap.gmail.comのソリューション例

  1. ルートCA証明書を決定します。

    openssl s_client -showcerts -connect imap.gmail.com:993
    

    この場合、ルートCAはEquifax Secure Certificate Authorityであることがわかります

  2. ダウンロード ルートCA証明書
  3. 情報と比較して、ダウンロードした証明書に適切なSHA-1および/またはMD5フィンガープリントがあることを確認します found here
  4. javax.net.ssl.trustStoreの証明書をインポート:

    keytool -import -alias gmail_imap -file Equifax_Secure_Certificate_Authority.pem
    
  5. Javaコードを実行します
33
jb1

JDKで提供されているJREのトラストストアに証明書をインポートしましたが、直接インストールされたJREのJava.exeを実行しています。

編集

明確にするため、および以下の解説で誤解の泥沼を解決するために、使用するJREのcacertsファイルに証明書をインポートする必要がありますクライアントは通常JDKを持たないため、JDK内で出荷されることはほとんどありません。以下の解説で、そうでないことを示唆するものはすべて、ここで私の意図を表明していないとして無視されるべきです。

はるかに良い解決策は、cacertsファイルのコピーから始めて、ownトラストストアを作成し、具体的にJavaにそれを使用するように指示することです。システムプロパティjavax.net.ssl.trustStore.を介したもの

JDKのアップグレードによるcacertsファイルの変更を最新の状態に保つために、ビルドプロセスのこの部分をビルドする必要があります。

9
user207421

Eclipseを使用している場合は、EclipseでクロスチェックするだけですWindows-> Preferences ----> Java ---> Installed JREsは、現在のJREと、証明書を設定したJREを指します。 JREを削除せず、証明書がインストールされている場所にjreを追加しない場合

Windowsでは、次の手順を試すことができます:

  1. WebサイトからルートCA証明書をダウンロードします。
  2. ディレクトリ/lib/securityでJREを使用してファイルjssecacertsを検索します(コマンドSystem.out.println(System.getProperty("Java.home");を使用して、現在のJREのフォルダーを検索できます)。ファイルのバックアップを作成します。
  3. プログラムをダウンロード portecle
  4. Portecleでjssecacertsファイルを開きます。
  5. パスワードを入力してください:changeit。
  6. ダウンロードした証明書をporticleでインポートします([ツール]> [信頼できる証明書のインポート])。
  7. 保存をクリックします。
  8. 元のファイルjssecacertsを置き換えます。
0
Ilya Lysenko

Pastebinごとに、proxy.tkk.com証明書をトラストストアに追加する必要があります。

0
Sean Baker

私の場合、Ubuntuに付属のデフォルトのOpenJDKを使用するのではなく、Oracleの公式JDK 10をインストールすることで問題が解決しました。これは私が従ったガイドです: https://www.linuxuprising.com/2018/04/install-Oracle-Java-10-in-ubuntu-or.html

0
acohen