web-dev-qa-db-ja.com

Javaのサーバー名表示(SNI)

誰かがJavaでサーバー名を表示してHTTP接続を始めるのを手伝ってくれる?

管理しているサイトからコンテンツをリクエストしようとしています。 ApacheのHttpClientライブラリを使用していますが、WebサイトがHTTPSにSNIのみを使用しており、DefaultHttpClientでSNIが有効になっていないため、安全なコンテンツのリクエストが失敗します。 ApacheのHttpClientライブラリ内でこれにアプローチする方法についての説明を探しましたが、最終的にはこのドキュメントが表示されます: http://hc.Apache.org/httpclient-3.x/sslguide.html =、これは古くなっています(HttpClientとHttpCoreがApacheのcommonsパッケージの一部であったときのコードバックを参照しています)。

それで...何か助けはありますか?

12
JellicleCat

あなたは追跡したいかもしれません https://issues.Apache.org/jira/browse/HTTPCLIENT-1119

Java 7の基礎となるクライアント実装はそれをサポートでき、SSLSocketImpl#setHost(Sun.net.www.protocol.https.HttpsClientによって呼び出されます)を介して機能を公開します

Java 7使用

    new URL("https://cmbntr.sni.velox.ch/").openStream()

hTTPCLIENT-1119が修正されるまで

11
cmbntr

これは私がorg.Apache.httpcomponentsのhttpclient v4.3 +でそれをした方法です

private HttpClientConnectionManager createConnectionManager(final SSLContext ctx) {
    LOG.info("Creating sslConnectionSocketFactory");
    final SSLConnectionSocketFactory sslSF = new SSLConnectionSocketFactory(ctx) {

        @Override
        protected void prepareSocket(SSLSocket socket) throws IOException {
            try {
                System.out.println("************ setting socket Host property *************");
                PropertyUtils.setProperty(socket, Host, Constants.SNI_Host);
            } catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException ex) {
                LOG.error(ex.getMessage());
            }
            super.prepareSocket(socket); 
        }

    };

    LOG.info("Creating connectionRegistry");
    final Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
            .register("https", sslSF)
            .build();

    LOG.info("Creating poolingConnectionManager");
    final PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry);
    connectionManager.setDefaultMaxPerRoute(MAX_CONNECTIONS_PER_ROUTE);
    connectionManager.setMaxTotal(MAX_CONNECTIONS);

    return connectionManager;
}

そして、これが私がHttpClientを作成した方法です

final KeyManager[] keyManagers = createKeyManagers();
final TrustManager[] trustManagers = createTrustManagers();
final SSLContext ctx = createSslContext(keyManagers, trustManagers);

final HttpClientConnectionManager connectionManager = createConnectionManager(ctx);

LOG.info("Creating httpClient");
HttpClient httpClient = HttpClients
        .custom()
        .setConnectionManager(connectionManager)
        .build();
5
shreyas

以下で説明する短い修正を加えてください。 TLS in SNI with Java clients SNIサーバーサポートをJDK 7に追加し、X509ExtendedKeyManagerと一緒に使用することが可能です。

1
SkateScout

私にとってうまくいったのは、Apache構成でServerNameを正しく構成することでした。

/etc/Apache2/sites-avaible/default

<VirtualHost *:443>
  ServerName foo.domain.com
  ...
</VirtualHost>

https://stackoverflow.com/a/8058839/2088282 で述べたように。

1
Giovanni Silva

この問題は Java 7 で修正されたようです。

0
a.drew.b