0

https の使用を強制する外部 Web サービスとアプリケーションを統合する必要があります。この Web サービスの作成者は、https 要求を行うために使用する .crt ファイルを提供してくれました。調査の結果、セキュリティで保護された https アクセスに KeyStore クラスを使用する次のコードが見つかりました。

        KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
        FileInputStream instream = new FileInputStream(new File(file));
        try {
            trustStore.load(instream, password.toCharArray());
        } finally {
            instream.close();
        }

        SSLContext sslcontext =
                SSLContexts.custom().loadTrustMaterial(trustStore, new TrustSelfSignedStrategy()).build();
        SSLConnectionSocketFactory sslsf =
                new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1.2"}, null,
                                               BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
        HttpClients.custom().setSSLSocketFactory(sslsf).build();

このコードでは、KeyStore には入力ストリームとパスワード trustStore.load(instream, password.toCharArray())が必要です。ただし、私が理解しているように、.crt ファイルを使用する場合はパスワードは必要ありません。したがって、証明書をロードするこの方法は私には適していません。同時に、これまでに発見したことから、ここで提供したコードは、SSL 証明書を使用するように HttpClient を構成する唯一の方法です。.crt 証明書を使用するために HttpClient を構成する回避策はありますか?

ありがとう、

アンドレイ

4

2 に答える 2

1

Web サービスは、自己署名証明書 (つまり、既知の CA によって署名されていない) を提供していると思います。Java の cacerts ファイルにある既知の CA によって既に署名されている場合は、何もする必要はありません。

それ以外の場合は、いくつかのオプションがあります。

  1. 証明書をグローバル cacerts キーストアにインポートします
  2. アプリケーション固有のキーストアを使用してアプリケーションを起動します

どちらの場合も、最初に crt ファイルを Java が使用する jks キーストアに変換する必要があります。これは次の方法で実行できます。

$ keytool -import -keystore mykeystore.jks -storepass horsestaple

keytool では、horsestaplejks ストアを作成するためにパスワード (上記) を指定する必要があることに注意してください。そこには何でも入れることができます。あなたが言及したように、公開 Web サイトの証明書はパスワード保護を必要とせず、結局のところ公開されています。

オプション 1 を実行している場合は、cacerts のバックアップを作成し、mykeystore.jks の代わりに cacerts ファイルを提供します。cacerts の場所については、以下のリンクを参照してください。Java はデフォルトで cacert をロードするため、このオプションの設定はすべて完了しています。追加の構成を行わなくても、アプリケーションは HTTPS 経由で Web サービスに接続する必要があります。

オプション 2 を実行している場合は、少なくともテスト フェーズではおそらく推奨されますが、このパラメーターを使用してアプリケーションを実行する必要があります。

-Djavax.net.ssl.trustStore=mykeystore.jks

これは JVM パラメータであるため、適切に指定してください。これは、アプリケーションの実行方法によって異なります。

この場合、インポートされた証明書しかないため、他の HTTPS 接続は機能しないことに注意してください。これを回避するには、最初に標準の cacerts を一時的な場所にコピーし、そこにキーをインポートして、上記のコマンドでそれを使用します。これにより、すべての標準証明書に加えて、必要な証明書が提供されます。

オプション 2 のわずかな欠点は、新しい証明書が追加または取り消された場合、アプリケーション固有のキーストアが更新されないことです。これが懸念される場合は、キーストアをオンザフライでマージできます。次に例を示します。

どちらの場合でも、次の例のように、標準の URL フェッチを実行できるようになりました。

すなわち:

final URL url = new URL("https://example.com");
try(final InputStream in = url.openStream()){
  //…
}

詳細はこちら:

  • Keytool と一般的な証明書の情報

https://docs.oracle.com/cd/E19830-01/819-4712/ablqw/index.html

  • カサートの場所

http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/keytool.html

  • 自己署名証明書をインポートするためのその他のオプション

デフォルトですべての Java アプリケーションが利用できる Java キーストアに自己署名証明書を適切にインポートする方法は?

お役に立てれば。

于 2016-08-10T01:37:35.083 に答える