9

Java URLクラスを使用すると、外部HTTPSサーバー(本番サイトなど)に接続できますが、ローカルURLを使用すると、次の例外が発生します。

"SunCertPathBuilderException: unable to find valid certification path to requested target".

有効な認定パスを取得するにはどうすればよいですか?

編集:私は直接接続を作成するためにこのURLを使用していません、私はURLをに渡します、itext PDFReaderそしてそれは接続の問題を抱えています。

4

6 に答える 6

13

これは、このスレッドのアイデアのいくつかを組み込み、ネット上のコードと一緒にまとめた私のソリューションです。この関数を呼び出すだけで、HttpsURLConnection のデフォルトの Trust Manager と HostName Verifier が設定されます。これは、すべての HttpsURLConnections に影響するため、一部の人にとっては望ましくない場合がありますが、単純なプロキシを作成しているだけなので、うまくいきました。

private void setTrustAllCerts() throws Exception
{
    TrustManager[] trustAllCerts = new TrustManager[]{
        new X509TrustManager() {
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                return null;
            }
            public void checkClientTrusted( java.security.cert.X509Certificate[] certs, String authType ) { }
            public void checkServerTrusted( java.security.cert.X509Certificate[] certs, String authType ) { }
        }
    };

    // Install the all-trusting trust manager
    try {
        SSLContext sc = SSLContext.getInstance( "SSL" );
        sc.init( null, trustAllCerts, new java.security.SecureRandom() );
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        HttpsURLConnection.setDefaultHostnameVerifier( 
            new HostnameVerifier() {
                public boolean verify(String urlHostName, SSLSession session) {
                    return true;
                }
            });
    }
    catch ( Exception e ) {
        //We can not recover from this exception.
        e.printStackTrace();
    }
}
于 2009-05-13T19:08:45.573 に答える
3

おそらくを設定する必要がありますHostnameVerifier。接続する前に、接続オブジェクトに追加する必要があります

HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setHostnameVerifier(new HostnameVerifier() {
  public boolean verify(String hostname, SSLSession session) {
    // check hostname/session
    return true;
  }
});
conn.connect();
// read/write...

必要に応じて、確かにいくつかの実装があります。HttpClientプロジェクトも確認することをお勧めします。

于 2008-12-17T03:00:52.507 に答える
3

もう1つ確認すべきことは、TrustManager使用している. このエラー メッセージは、サーバーによって提示された証明書が信頼されたルートによって署名されていないことを示しています。作成された SSL ソケットを直接制御することはできないため、サーバーの証明書チェーンのルート CA でセットアップされたで独自のソケットを初期化するのが最善の策だと思います。次に、このコンテキストをデフォルトとして設定します。SSLContextTrustManager

これは、Java 6 を使用していることを前提としています。API は、Java 5 でより制限されています。デフォルトを取得できますがSSLSocketFactory、それを設定する標準的な方法はありません。

于 2008-12-17T07:06:17.533 に答える
0

それが不平を言っている問題は、SSL接続を作成するときに、サーバーがクライアントに有効な証明書を提示する必要があることです。Javaで適切なエンドポイントを作成できますが(HTTPServerSocketで実行できると思います)、設定するにはハッキングが必要になります。SSLを正しく処理するもの(Apache、lighttpなど)を使用してローカルWebサーバーをセットアップし、opensslツールを使用して自己署名証明書を作成する方がおそらく簡単です。

更新しました

これがJavaアルマナックの例です。http://www.exampledepot.com/egs/javax.net.ssl/Server.html

SSLサーバーソケットには、認証のためにクライアントに送信する証明書が必要です。証明書は、場所を明示的に指定する必要があるキーストアに含まれている必要があります(デフォルトはありません)。例に続いて、使用するSSLサーバーソケットのキーストアを作成および指定する方法について説明します。

try {
    int port = 443;
    ServerSocketFactory ssocketFactory = SSLServerSocketFactory.getDefault();
    ServerSocket ssocket = ssocketFactory.createServerSocket(port);

    // Listen for connections
    Socket socket = ssocket.accept();

    // Create streams to securely send and receive data to the client
    InputStream in = socket.getInputStream();
    OutputStream out = socket.getOutputStream();

    // Read from in and write to out...

    // Close the socket
    in.close();
    out.close();
} catch(IOException e) {
}

javax.net.ssl.keyStoreシステムプロパティを使用して、証明書のキーストアを指定します。

> java -Djavax.net.ssl.keyStore=mySrvKeystore -Djavax.net.ssl.keyStorePassword=123456 MyServer
于 2008-12-17T02:56:01.687 に答える
0

また、「keytool」ユーティリティを使用して、ローカルホスト サーバーが使用している証明書 (自己署名されていると仮定します) を JVM のキーストアに追加すると役立つ場合があります。これには、JVM に「この証明書を信頼できる」と伝える効果があるはずです。

于 2008-12-17T14:43:39.217 に答える
0

非常に信頼できる TrustManager (すべてを受け入れる) をインストールする静的メソッド (dev のみ) を実行し、常に true を返す hostnameVerifier を追加しました ( sblundyに感謝します)。

于 2008-12-17T23:55:59.790 に答える