なぜjavaはSSLハンドシェイク中にクライアント証明書を送信しないのでしょうか?
質問
安全なウェブサービスに接続しようとしています。
鍵屋とトラストストアが正しく設定されているにもかかわらず、ハンドシェイクに失敗してしまいました。
数日間のフラストレーション、終わりのないグーグル検索、および周囲への問い合わせの後、唯一の問題は、java がハンドシェイク中にクライアント証明書をサーバーに送信しないことを選択したことだとわかりました。
具体的には
- サーバーがクライアント証明書 (CN=RootCA) を要求した - すなわち "ルート CA" によって署名された証明書を私に与えてください。
- Java は鍵ストアを調べ、私のクライアント証明書を見つけましたが、それは "SubCA" によって署名され、さらに "RootCA" によって発行されました。これは、トラストストアをわざわざ調べようとはしませんでした......。
- 悲しいことに、私が "SubCA" 証明書をキーストアに追加しようとしたとき、それはまったく役に立ちませんでした。私は、証明書が鍵ストアに読み込まれるかどうかを確認しました。しかし、KeyManager は、クライアント証明書以外のすべての証明書を無視します。
- 上記のすべてが、java がサーバーの要求を満たす証明書がないと判断し、何も送信しないという事実につながります。
私の質問です。
- 私が "SubCA" 証明書を鍵ストアに追加して、quot;証明書チェーンを破壊したとか、KeyManager がクライアント証明書だけをロードして残りを無視したとかいうことはありえますか? (Chromeとopensslはそれを理解することができたのに、なぜjavaはできないのでしょうか?- ちなみに、quot;SubCA"の証明書は、常に信頼できる機関として別々に提示されるので、Chromeは明らかにハンドシェイク中にクライアント証明書と一緒に正しくパックします)
- これはサーバー側の正式な "設定の問題" なのでしょうか?サーバーはサード パーティです。私は、サーバーが "SubCA"機関が提供したものであるため、その機関が署名した証明書を要求することを期待します。Chromeとopensslでこれが動作するのは、制限が少ないからで、javaは本に従って失敗しているだけだと思われます。
私はこのために汚い回避策を何とかまとめましたが、あまり満足していないので、誰かが私のためにこのことを明確にすることができれば嬉しく思います。
どのように解決するのですか?
クライアント証明書とその秘密鍵があるエントリと関連付けることなく、中間 CA 証明書をキーストアにインポートしている可能性があります。これを確認するには
keytool -v -list -keystore store.jks
. エイリアスエントリごとに1つの証明書しか取得できない場合、それらは一緒ではありません。
あなたの秘密鍵を持つキーストアのエイリアスに、証明書とそのチェーンを一緒にインポートする必要があります。
どの鍵ストアエイリアスが秘密鍵を持っているかを調べるには、次のようにします。
keytool -list -keystore store.jks
を使用します (ここでは JKS ストアタイプを想定しています)。これは、次のようなことを教えてくれます。
Your keystore contains 1 entry
myalias, Feb 15, 2012, PrivateKeyEntry,
Certificate fingerprint (MD5): xxxxxxxx
ここでは、エイリアスは
myalias
. もし
-v
を追加すると
Alias Name: myalias
.
まだ別途持っていない場合は、鍵屋からクライアント証明書をエクスポートします。
keytool -exportcert -rfc -file clientcert.pem -keystore store.jks -alias myalias
これでPEMファイルができるはずです。
テキストエディタを使って(あるいは
cat
) を使って、ファイル (仮に
bundle.pem
にクライアント証明書と中間CA証明書(必要ならルートCA証明書も)、クライアント証明書が先頭でそのすぐ下に発行者証明書が来るように準備します。
これは次のようになります。
-----BEGIN CERTIFICATE-----
MIICajCCAdOgAwIBAgIBAjANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJVSzEa
....
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIICkjCCAfugAwIBAgIJAKm5bDEMxZd7MA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNV
....
-----END CERTIFICATE-----
さて、このバンドルを秘密鍵のあるエイリアスにインポートし直します。
keytool -importcert -keystore store.jks -alias myalias -file bundle.pem
関連
-
配列定数は初期化子でのみ使用可能です。
-
List list = new ArrayList(); Error: ArrayList は型に解決できません。
-
java send https request prompt java.security.cert.について。
-
Javaがリソースリークに遭遇した:'input'が閉じない 解決方法
-
コンストラクタDate()が未定義である問題
-
[解決済み】.cer証明書をjava keystoreにインポートする方法は?
-
[解決済み】Java HTTPSクライアント証明書認証
-
[解決済み】Javaクライアントでサーバーの自己署名入りssl証明書を受け入れる。
-
[解決済み] [Solved] javax.net.ssl.SSLHandshakeException の解決: sun.security.validator.ValidatorException: PKIX パスの構築に失敗しました エラー?
-
[解決済み] HTTPS/SSL上のJavaクライアント証明書
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
Springの設定でxsdファイルのバージョン番号を設定しない方が良い理由
-
Java の switch case 文で必要な定数式の問題の解決法
-
Javaクラスが "Error occurred during initialization of boot layer "というエラーで実行される。
-
ブートレイヤーの初期化中にエラーが発生しました java.lang.module.FindException: モジュールが見つかりません
-
Junitのユニットテストはjava.lang.Testを報告します。
-
SpringBoot 起動エラー java.nio.charset.MalformedInputException: 入力長 = 2 解決
-
ecplise プロンプトが表示されます。"選択したものは起動できません。" "最近の起動はありません。"
-
Java JDKのダイナミックプロキシ(AOP)の使用と実装の原理分析
-
WeChat小プログラム Bluetooth通信 Bluetoothモジュールデモ
-
[解決済み】Javaキーストアに既存のX.509証明書と秘密鍵をインポートして、SSLで使用するにはどうすればよいですか?