tl;dr: カスタム CA を永続キーストアに追加せずに使用しています。
HTTPS を使用してリモート サーバーに接続する Java アプリケーションを作成しています。接続用のコードは準備ができていますが、サーバーの SSL 証明書はJava の CA ルート証明書ストアにないStartSSLによって署名されています。
このコードを使用して、次のような Web サイトから有効な証明書情報を取得しますhttps://www.google.com/
。
Response Code : 200
Cipher Suite : TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
Cert Type : X.509
Cert Hash Code : -1643391404
Cert Public Key Algorithm : RSA
Cert Public Key Format : X.509
Cert Type : X.509
Cert Hash Code : 771393018
Cert Public Key Algorithm : RSA
Cert Public Key Format : X.509
Cert Type : X.509
Cert Hash Code : 349192256
Cert Public Key Algorithm : RSA
Cert Public Key Format : X.509
同じコードが私のドメインに対して をスローしSSLHandshakeException
ます ( と呼びましょうhttps://www.example.com/
)。
もちろん、証明書をキーストアに手動で追加することもできますkeytool
(おそらく を使用してもRuntime.exec("keytool ...")
) が、これは汚い方法です。現在計画しているのは、アプリケーション ファイルに StartSSL ルート証明書を追加して配布し、実行時に一時的なキーストアにロードすることです。このようにして、「実際の」キーストアは変更されません。
こことここで読んだことから、 のようないくつかのクラスを台無しにする必要がありますTrustManager
。検証を完全にオフにする方法も見つけましたが、暗号化された通信の目的全体を排除するように見えるため、これは私が望むものではありません。
まさに私がやりたいことをしているように見えるコード行をいくつか見つけましたが、このメソッドを呼び出す方法、つまりどの値を引数として渡すかわかりません:
public class SSLClasspathTrustStoreLoader {
public static void setTrustStore(String trustStore, String password) throws Exception {
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("X509");
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
InputStream keystoreStream = SSLClasspathTrustStoreLoader.class.getResourceAsStream(trustStore);
keystore.load(keystoreStream, password.toCharArray());
trustManagerFactory.init(keystore);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustManagers, null);
SSLContext.setDefault(sc);
}
}
誰かが以前に同様の状況にあったことがありますか? この問題を処理する方法についてアドバイスをいただければ幸いです。上記のコードを実行するのを手伝っていただければ、本当にうれしいです!