詳細なドキュメントが必要な場合は、JSSE リファレンス ガイド、より具体的にはSSLContext セクションを参照してください。
デフォルト値 ( に渡す場合null
)SSLContext.init(...)
はデフォルトで適切ですが、これらのデフォルト値が何であるかを理解したい場合があります (カスタマイズのセクションを参照してください)。
キーストアにはデフォルトはありません (トラストストアだけです。クライアント証明書認証が必要な場合は、とにかくカスタマイズする必要があります)。
SSLContext
通常、次のように初期化できます。
KeyStore ks = KeyStore.getInstance(...); // Load the keystore
ks.load(...); // Load as required from the inputstream of your choice, for example.
KeyStore ts = KeyStore.getInstance(...); // Load the truststore
ts.load(...);
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks, <the key password>);
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ts);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
おそらく、キーストアとトラストストアの違いについて、この回答にも興味があるかもしれません。要するに、どちらもストレージの意味での「キーストア」ですが、キーストアは、証明書 (+チェーン) と関連する秘密鍵 (つまり、サーバー上のサーバー証明書と秘密鍵、およびクライアント証明書と秘密鍵) を格納する場所です。トラストストアは、リモート パーティがその証明書を提示するときに、信頼できる CA 証明書またはリモート証明書 (証明書ではないため、秘密鍵なし) を格納する場所です。
キー/証明書ファイルをどうするかに関しては、この回答PCKS12
で説明されているように構築できるtype のキーストアを使用するのが最も簡単です。
編集:(コメントに続く)
それで、私がサーバーであり、まだ SSL クライアント認証を行っていない場合、null の TrustManager を回避できることは正しく理解されていますか?
はい。
しかし、クライアント認証を行う場合、接続できるすべてのクライアントの公開鍵を含む TrustManager を提供する必要がありますか?
通常はありません。これらのクライアント証明書を発行した CA の CA 証明書を提供します。このインフラストラクチャがない場合 (または構築中でクライアント証明書がまだない場合) は、独自の PKI を作成するか、有名な CA からクライアント証明書を購入することを検討する必要があります。
自己署名証明書を (任意の CA から独立して) 受け入れ、事前定義されたリストのフィンガープリントを使用してそれらを検証する TrustManager を構築することもできますが、これには多くの問題があります (特に、サーバーが正しい証明書を要求する方法)。 )、PKI の目的の一部を複製することになる可能性があります。あなたが何をしているのかをもっと理解しない限り、それは私がお勧めするものではありません.
それは少し残念です。承認されたクライアントのフィンガープリントを取得してから、実際のクライアントが認証したフィンガープリントと比較する必要がある前に、リクエスト URL を取得するまで待っていればよかったのにと思いました。
ここでは、まったく別の側面について話しています。要求された URL を最初に取得したい場合は、証明書を要求する前に、再ネゴシエーションを使用する必要があります。HTTP レイヤーはSSLEngine
、新しいハンドシェイクをトリガーするように要求するために、 と通信する必要があります (クライアント証明書を要求するように設定されています)。
SSLEngine
一般に、Java での SSL/TLS への簡単な道筋ではありませんが、非同期再ネゴシエーションは非常にトリッキーになる可能性があります。実際、そのセマンティクスはアプリケーション層ではあまり明確ではありません。HTTP リクエストを受信した後に再ネゴシエーションをトリガーすることは十分に可能ですが、同時にレスポンスを送信している最中でもあります (パイプライン化された非同期のリクエスト/レスポンスがある可能性があるため)。技術的には、新しいハンドシェイクは両方のパイプに影響します。
全体として、再ネゴシエーションかどうかは、クライアント証明書をどのように信頼するかを確認することとはまったく関係ありません。アプリケーション レイヤー (SSL/TLS レイヤーではなく) に証明書の検証を行う方法を本当に実行したい場合は、X509TrustManager
すべてを信頼する (SSL/TLS レイヤーでの検証をバイパスする)を作成する必要があります。アプリケーションにSSLSession
(ピア証明書)から証明書を取得させ、そこで検証を行います。全体として、これは自己署名証明書を受け入れて手動で検証するのと非常によく似ています。それは可能ですが、PKI モデルからステップアウトすることになり、そのためにカスタム コードが必要になります (デフォルトで使用されるように API を使用するのではなく)。
これらすべてに慣れていない場合は、このアプローチを避けます。テスト用の CA を設定してみて、最初にその仕組みを学んでください。CA の使用または手動の指紋認証の実行に関する全体的な問題は、最終的にはより管理上の問題になります。それは、関係者間で証明書を配布する方法によって定義されます。
また、<the key password>
ここで何をしていますか?これは、どこかのホスティング施設の無人サーバーで実行することになっています。起動中 (たとえば、停電の後) に誰かがパスワードを入力するのを待つことはできません。
パスワードを設定する必要があります。ほとんどのサーバーは、必要に応じて構成ファイルから読み取ります (さらに悪いことに、ハードコーディングすることもできます)。