SSL証明書のサーバー名はどのように解決されますか/keytoolを使用して代替名を追加できますか?
質問
これらは、わかりやすくするために別々の質問として表現されることがありますが、すべて同じ問題に関連しています。
SSL証明書のサーバー名はどのように解決されるのですか?
なぜブラウザは証明書のCNフィールドを使用するようですが、Javaのメカニズムは"subject alternative names"だけを見るようなのでしょうか?
keytoolを使用して、SSL証明書に代替名を追加することは可能でしょうか? そうでない場合、代わりにopenSSLを使用することは良い選択でしょうか?
ほんの少しの背景です。 私は、メインサーバーがHTTPSを使用していくつかのサーバーと通信するようにする必要があります。明らかに、すべてのサーバーの SSL 証明書を購入したくないので (多数ある可能性があります)、自己署名証明書を使用したいと思います (私はそれらを生成するために keytool を使用してきました)。OSで証明書を信頼済みとして追加した後、ブラウザ(IEとChrome)は喜んで信頼済みとして接続を受け入れる。しかし、証明書をJavaのcacertsに追加した後でも、Javaはまだ信頼できる接続として受け入れず、以下のExceptionをスローします。
原因:java.security.cert.CertificateException: サブジェクトの代替名がない 現在 at sun.security.util.HostnameChecker.matchIP(HostnameChecker.java:142)。 at sun.security.util.HostnameChecker.match(HostnameChecker.java:75)。 at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkIdentity(X509T rustManagerImpl.java:264) at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted( X509TrustManagerImpl.java:250) at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Clien tHandshaker.java:1185) ... 14件以上
ここからコピーした独自のHostNameVerifierを実装することで、Javaに証明書を信頼させることができることがわかりました。 com.sun.jbi.internal.security.https.DefaultHostnameVerifier を試してみました(ちなみに、HostnameVerifierの引数として渡されたホスト名は正しいので、受理されているはずだと思います)。
ホスト名には、証明書フィールドのCNを使用しています(通常はIPアドレス)。
どなたか、私が何か間違ったことをしているかどうか教えていただき、正しい方向に導いていただけないでしょうか。
どのように解決するのですか?
ホスト名の検証をどのように行うべきかは RFC 6125 これは非常に新しいもので、すべてのプロトコルにこの方法を一般化したものです。 RFC 2818 というように、HTTPSに特化したものでした。(Java 7 が RFC 6125 を使用しているかどうかもわからないし、これでは新しすぎるかもしれない)。
から RFC 2818 (第 3.1 節) :
dNSName タイプの subjectAltName 拡張が存在する場合、それを ID として使用しなければなりません (MUST)。 をIDとして使用しなければならない。そうでない場合は、証明書のSubjectフィールドにある(最も具体的な)Common Name フィールドが使用されなければならない(MUST)。しかし Common Nameの使用は既存の慣行であるが、非推奨であり、認証機関はCommon Nameの使用を推奨する。 認証機関は、代わりにdNSNameを使用することが推奨されます。
[...]
場合によっては、URIはホスト名ではなくIPアドレスで指定されることがあります。 として指定される場合があります。この場合、iPAddress subjectAltName が証明書内に存在し、URI の IP と正確に一致する必要があります。 が証明書内に存在し、URI の IP と正確に一致しなければなりません。
基本的に、あなたが抱えている特定の問題は、ホスト名ではなく IP アドレスを CN に使用しているという事実に起因しています。特に、RFC 2818 の "most specific" が明確に定義されていないため (RFC 6215 の議論を参照)、すべてのツールがこの仕様に厳密に従うわけではないので、一部のブラウザでは動作する可能性があります。
もしあなたが
keytool
,
をJava 7の時点では
keytool
には、サブジェクト代替名を含めるオプションがあります (ドキュメント内の
-ext
を使うことができます。
-ext san=dns:www.example.com
または
-ext san=ip:10.0.0.1
.
EDITです。
OpenSSLでSANを要求するには、以下のように変更します。
openssl.cnf
を使って明示的に場所を指定することができます (私の記憶では、グローバルな設定を編集したくない場合は、現在のディレクトリにあるコピーを選びます。
OPENSSL_CONF
環境変数)。
以下のオプションを設定します(最初に括弧内の適切なセクションを見つけます)。
[req]
req_extensions = v3_req
[ v3_req ]
subjectAltName=IP:10.0.0.1
# or subjectAltName=DNS:www.example.com
また、このために(設定ファイルで固定するのではなく)環境変数を使用する素晴らしいトリックがここにあります。 http://www.crsr.net/Notes/SSL.html
関連
-
Collections.sortがdoubleでソートできない問題を完璧に解決する。
-
アノテーション「@Retention」の役割
-
maven レポート エラー 解決不可能な親POM
-
git pull appears現在のブランチに対するトラッキング情報がありません。
-
[解決済み] Mavenを使用して、依存関係を持つ実行可能なJARを作成するにはどうすればよいですか?
-
[解決済み] OpenSSLを使用して自己署名入りSSL証明書を生成する方法を教えてください。
-
[解決済み】JSP 2を使用して、JSPファイル内のJavaコードを回避するにはどうすればよいですか?
-
[解決済み] [Solved] javax.net.ssl.SSLHandshakeException の解決: sun.security.validator.ValidatorException: PKIX パスの構築に失敗しました エラー?
-
[解決済み】トラストストアとキーストアの比較 - keytoolで作成する場合
-
[解決済み] 共通名(CN)と件名代替名(SAN)はどのように連携するのですか?
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
Eclipseは、ポップアップA Java Exception has occurred.を実行し、エラーException in threadの解決策を報告します。
-
java.sql.SQLException: executeQuery()でデータ操作文を発行できません。
-
Javaでよくある構文エラー
-
javaの非静的メソッドを静的に参照することができない
-
名前 'XXX' を持つ Bean の作成に失敗しました。自動依存関係の注入に失敗しました 解決方法
-
無効なメソッド宣言
-
FindBugの使用概要
-
JDK8 の Optional.of と Optional.ofNullable メソッドの違いと使い方を説明する。
-
Java基礎 - マッピングとQ/A
-
[解決済み] ドメイン名ではなく、IPアドレスに対してSSL証明書を発行することは可能ですか?