[解決済み] 特定の接続で異なる証明書を使用するにはどうすればよいですか?
質問
当社の大規模なJavaアプリケーションに追加しているモジュールは、他社のSSLで保護されたウェブサイトと通信する必要があります。 問題は、そのサイトが自己署名証明書を使用していることです。 私は中間者攻撃に遭遇していないことを確認するために証明書のコピーを持っており、私はサーバーへの接続が成功するように、この証明書を私たちのコードに組み込む必要があります。
これが基本的なコードです。
void sendRequest(String dataPacket) {
String urlStr = "https://host.example.com/";
URL url = new URL(urlStr);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setMethod("POST");
conn.setRequestProperty("Content-Length", data.length());
conn.setDoOutput(true);
OutputStreamWriter o = new OutputStreamWriter(conn.getOutputStream());
o.write(data);
o.flush();
}
自己署名証明書の処理を追加しないと、conn.getOutputStream()で次のような例外が発生して終了します。
Exception in thread "main" 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
....
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
....
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
理想的には、私のコードはJavaに、この自己署名証明書を、アプリケーションのこの場所だけで、他のどこにも受け入れないように教える必要があります。
JREの認証局ストアに証明書をインポートすれば、Javaがそれを受け入れるようになることは分かっています。 同じJREを使用している他のすべてのJavaアプリケーションに影響しますし、他のJavaアプリケーションがこのサイトにアクセスする確率はゼロであるにもかかわらず、私はそれが好きではありません。 UNIXでは、この方法でJREを変更するためにはアクセス権を取得しなければなりません。
また、いくつかのカスタムチェックを行うTrustManagerのインスタンスを作成できることもわかりました。 この証明書以外のすべてのインスタンスを本物のTrustManagerに委ねるTrustManagerを作成することもできそうです。 しかし、その TrustManager はグローバルにインストールされるようで、我々のアプリケーションからの他のすべての接続に影響すると思われ、私にとってもあまり良い感じではない。
自己署名証明書を受け入れるためにJavaアプリケーションをセットアップするための好ましい、標準的な、または最良の方法は何ですか? 私が上で考えている目標をすべて達成できるのか、それとも妥協しなければならないのか? ファイルやディレクトリ、コンフィギュレーション設定を含み、コードをほとんど含まないオプションはありますか?
解決方法は?
を作成します。
SSLSocket
ファクトリーを自分で作成し、それを
HttpsURLConnection
を使用して接続します。
...
HttpsURLConnection conn = (HttpsURLConnection)url.openConnection();
conn.setSSLSocketFactory(sslFactory);
conn.setMethod("POST");
...
を1つ作成することになります。
SSLSocketFactory
を作成し、保持しています。以下は、それを初期化する方法のスケッチです。
/* Load the keyStore that includes self-signed cert as a "trusted" entry. */
KeyStore keyStore = ...
TrustManagerFactory tmf =
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(keyStore);
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, tmf.getTrustManagers(), null);
sslFactory = ctx.getSocketFactory();
キーストアの作成でお困りの方は、コメントください。
キーストアを読み込む例です。
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(trustStore, trustStorePassword);
trustStore.close();
PEM形式の証明書でキーストアを作成するには、以下のようにコードを記述します。
CertificateFactory
でインポートするか、あるいは
keytool
をJDKからダウンロード(キーツール
はしない。
は、"キーエントリ" に対して動作しますが、"信頼されたエントリ" に対しては問題ありません)。
keytool -import -file selfsigned.pem -alias server -keystore server.jks
関連
-
Java Error スレッド "AWT-EventQueue-0" で例外発生 java.lang.
-
myeclipseでコンパイルするとAntエラーが発生する javaの例外が発生しました。
-
Dateが型に解決できない問題を解決する
-
スキャナは、タイプに解決することはできません最もルーキー初心者の質問
-
JavaMailのメール送信が失敗するケースとその説明の分析
-
スレッド "main" で例外発生 java.lang.ArrayIndexOutOfBoundsException: 0 at One1.main(One1.java:3)
-
[解決済み] android.os.NetworkOnMainThreadException' を修正するにはどうすればよいですか?
-
[解決済み] Javaでメモリーリークを発生させるにはどうしたらいいですか?
-
[解決済み】要求されたターゲットへの有効な証明書パスが見つからない - 証明書をインポートしてもエラーが発生する
-
[解決済み] [Solved] javax.net.ssl.SSLHandshakeException の解決: sun.security.validator.ValidatorException: PKIX パスの構築に失敗しました エラー?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
スタイルが読み込まれず、ブラウザのコンソールでエラーが報告される。リソースはスタイルシートとして解釈されますが、MIMEタイプtext/htmlで転送されます。
-
javaの実行中に「javaの例外が発生しました」と表示された場合はどうすればよいですか?
-
eclipse で「アクセス制限: タイプ 'HttpServer' は API ではありません」というプロンプトが表示される。
-
アクセス制限について アプリケーションの種類がAPIでない(必要なライブラリの制限)。
-
javaの模造品QQ WeChatのチャットルーム
-
JDKの設定時にjava.dllが見つからない、java SE Runtime Environmentが見つからない問題が発生しました。
-
Intellij IDEAのエラー「CreateProcess error=2, system could not find specified file」に対する完璧な解決策です。
-
JQuery DataTable 详解
-
Java(1)仕上げの基本概念+eclipseのインストール構成
-
[解決済み】Javaクライアントでサーバーの自己署名入りssl証明書を受け入れる。