web-dev-qa-db-ja.com

リストストアとクリスマス - keytoolで作成する

私は、キーストアは通常プライベートキー/パブリックキーを保持し、トラストストアはパブリックキーのみを保持する(そしてあなたが通信しようとしている信頼できるパーティーのリストを表す)ことを理解しています。まあ、それが私の最初の仮定なので、それが正しくない場合は、おそらく私はあまりうまく始めていません...

私はkeytoolを使うときどのように/いつあなたが店を区別するかを理解することに興味を持っていました。

そのため、これまでにキーストアを作成しました。

keytool -import -alias bob -file bob.crt -keystore keystore.ks

これは私のkeystore.ksファイルを作成します。私は質問にyesと答えますが、bobを信頼しますか?しかし、これがキーストアファイルまたはトラストストアファイルを作成したかどうかは私にはわかりませんか?どちらかとしてファイルを使用するようにアプリケーションを設定できます。

-Djavax.net.ssl.keyStore=keystore.ks -Djavax.net.ssl.keyStorePassword=x
-Djavax.net.ssl.trustStore=keystore.ks -Djavax.net.ssl.trustStorePassword=x

System.setProperty( "javax.net.debug", "ssl")を設定すると、証明書が信頼できる証明書の下に表示されます(ただし、キーストアセクションの下には表示されません)。私がインポートしている特定の証明書は公開鍵しか持っていないので、SSL接続を介してBobにものを送信するためにそれを使用するつもりです(ただし、おそらく別の質問にお任せください)。

任意のポインターや明確化は大歓迎です。 keytoolの出力は、あなたがインポートしたものと同じものであり、その1つがキーストアであり、もう1つがトラストストアであるという単純な規約ですか? SSLなどを使うときの関係は何ですか?

224
Toby

確かに用語は少しわかりにくいですが、javax.net.ssl.keyStorejavax.net.ssl.trustStoreの両方を使用して、使用するキーストアを2つの異なる目的で指定します。キーストアにはさまざまな形式があり、必ずしもファイルではありません( この質問 を参照)。keytoolは、さまざまな操作(インポート/エクスポート/リスト/ ...)を実行するための単なるツールです。

javax.net.ssl.keyStoreおよびjavax.net.ssl.trustStoreパラメーターは、KeyManagersおよびTrustManagers(それぞれ)を構築するために使用されるデフォルトのパラメーターであり、SSL/TLS接続を行うときに使用するSSL/TLS設定を本質的に含むSSLContextを構築するために使用されますSSLSocketFactoryまたはSSLEngineを介して。これらのシステムプロパティは、デフォルト値の取得元であり、SSLContext.getDefault()によって使用され、たとえばSSLSocketFactory.getDefault()によって使用されます。 (これらはすべて、特定の目的でデフォルト値とその特定のSSLContextsを使用したくない場合、APIを介していくつかの場所でカスタマイズできます。)

KeyManagerTrustManagerの違い(したがってjavax.net.ssl.keyStorejavax.net.ssl.trustStoreの違い)は次のとおりです( JSSE ref guide から引用)。

TrustManager:リモート認証資格情報(および接続)を信頼するかどうかを決定します。

KeyManager:リモートホストに送信する認証資格情報を決定します。

(他のパラメーターが利用可能であり、そのデフォルト値は JSSE refガイド で説明されています。トラストストアにはデフォルト値がありますが、キーストアにはないことに注意してください。)

基本的に、javax.net.ssl.keyStoreのキーストアには秘密鍵と証明書が含まれますが、javax.net.ssl.trustStoreには、リモートパーティが証明書を提示するときに信頼できるCA証明書が含まれます。場合によっては、それらが1つの同じストアになることもありますが、多くの場合、個別のストアを使用する方がよい場合があります(特にファイルベースの場合)。

316
Bruno

一般的なユースケース/目的または素人の方法で説明するには

TrustStore:名前が示すとおり、通常は信頼できるエンティティの証明書を格納するために使用されます。プロセスは、信頼しているすべての信頼できる当事者の証明書の保管場所を維持できます。

keyStore:署名付き証明書とともにサーバーの鍵(公開鍵と秘密鍵の両方)を保管するために使用されます。

SSLハンドシェイク中

  1. クライアントがhttps://にアクセスしようとしました

  2. したがって、サーバーはSSL証明書(keyStoreに格納されています)を提供することによって応答します。

  3. これで、クライアントはSSL証明書を受け取り、それをtrustStoreを介して検証します(つまり、クライアントのtrustStoreには、それが信頼する事前定義済みの証明書のセットが既にあります)。そのようなものです:私はこのサーバーを信頼できますか?これは私が話そうとしているのと同じサーバーですか?仲介者による攻撃はありませんか。

  4. クライアントは、信頼しているサーバーと通信していることを確認したら、共有秘​​密キーを介してSSL通信を行うことができます。

注:ここでは、サーバー側のクライアント認証については何も話していません。サーバがクライアント認証も行いたい場合、サーバはクライアントを検証するためにtrustStoreも維持します。

キーストアファイルとトラストストアファイルに違いはありません。どちらも独自のJKSファイル形式のファイルです。区別は用途にあります:私の知る限りでは、JavaはSSL接続を作成するとき信頼する証明書を探すためにjavax.net.ssl.trustStoreによって参照されるストアだけを使用します。 keysとjavax.net.ssl.keyStoreについても同じです。しかし、理論的には、信頼ストアとキーストアに同じファイルを使用することをお勧めします。

23
musiKk

鍵ストアは秘密鍵を保管するためにサーバーによって使用され、トラストストアはアクセスするためにサーバーによって提供される公開鍵を保管するために第三者クライアントによって使用されます。私は本番アプリケーションでそれを行いました。 SSL通信用のJava証明書を生成する手順は次のとおりです。

  1. Windowsでkeygenコマンドを使用して証明書を生成します。

keytool -genkey -keystore server.keystore -alias mycert -keyalg RSA -keysize 2048 -validity 3950

  1. 自己証明書を証明します。

keytool -selfcert -alias mycert -keystore server.keystore -validity 3950

  1. 証明書をフォルダにエクスポートします。

keytool -export -alias mycert -keystore server.keystore -rfc -file mycert.cer

  1. 証明書をクライアントのトラストストアにインポートします。

keytool -importcert -alias mycert -file mycert.cer -keystore truststore

20
Akash5288