私は、キーストアは通常プライベートキー/パブリックキーを保持し、トラストストアはパブリックキーのみを保持する(そしてあなたが通信しようとしている信頼できるパーティーのリストを表す)ことを理解しています。まあ、それが私の最初の仮定なので、それが正しくない場合は、おそらく私はあまりうまく始めていません...
私は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などを使うときの関係は何ですか?
確かに用語は少しわかりにくいですが、javax.net.ssl.keyStore
とjavax.net.ssl.trustStore
の両方を使用して、使用するキーストアを2つの異なる目的で指定します。キーストアにはさまざまな形式があり、必ずしもファイルではありません( この質問 を参照)。keytool
は、さまざまな操作(インポート/エクスポート/リスト/ ...)を実行するための単なるツールです。
javax.net.ssl.keyStore
およびjavax.net.ssl.trustStore
パラメーターは、KeyManager
sおよびTrustManager
s(それぞれ)を構築するために使用されるデフォルトのパラメーターであり、SSL/TLS接続を行うときに使用するSSL/TLS設定を本質的に含むSSLContext
を構築するために使用されますSSLSocketFactory
またはSSLEngine
を介して。これらのシステムプロパティは、デフォルト値の取得元であり、SSLContext.getDefault()
によって使用され、たとえばSSLSocketFactory.getDefault()
によって使用されます。 (これらはすべて、特定の目的でデフォルト値とその特定のSSLContext
sを使用したくない場合、APIを介していくつかの場所でカスタマイズできます。)
KeyManager
とTrustManager
の違い(したがってjavax.net.ssl.keyStore
とjavax.net.ssl.trustStore
の違い)は次のとおりです( JSSE ref guide から引用)。
TrustManager:リモート認証資格情報(および接続)を信頼するかどうかを決定します。
KeyManager:リモートホストに送信する認証資格情報を決定します。
(他のパラメーターが利用可能であり、そのデフォルト値は JSSE refガイド で説明されています。トラストストアにはデフォルト値がありますが、キーストアにはないことに注意してください。)
基本的に、javax.net.ssl.keyStore
のキーストアには秘密鍵と証明書が含まれますが、javax.net.ssl.trustStore
には、リモートパーティが証明書を提示するときに信頼できるCA証明書が含まれます。場合によっては、それらが1つの同じストアになることもありますが、多くの場合、個別のストアを使用する方がよい場合があります(特にファイルベースの場合)。
一般的なユースケース/目的または素人の方法で説明するには
TrustStore:名前が示すとおり、通常は信頼できるエンティティの証明書を格納するために使用されます。プロセスは、信頼しているすべての信頼できる当事者の証明書の保管場所を維持できます。
keyStore:署名付き証明書とともにサーバーの鍵(公開鍵と秘密鍵の両方)を保管するために使用されます。
SSLハンドシェイク中
クライアントがhttps://にアクセスしようとしました
したがって、サーバーはSSL証明書(keyStoreに格納されています)を提供することによって応答します。
これで、クライアントはSSL証明書を受け取り、それをtrustStoreを介して検証します(つまり、クライアントのtrustStoreには、それが信頼する事前定義済みの証明書のセットが既にあります)。そのようなものです:私はこのサーバーを信頼できますか?これは私が話そうとしているのと同じサーバーですか?仲介者による攻撃はありませんか。
クライアントは、信頼しているサーバーと通信していることを確認したら、共有秘密キーを介してSSL通信を行うことができます。
注:ここでは、サーバー側のクライアント認証については何も話していません。サーバがクライアント認証も行いたい場合、サーバはクライアントを検証するためにtrustStoreも維持します。
キーストアファイルとトラストストアファイルに違いはありません。どちらも独自のJKSファイル形式のファイルです。区別は用途にあります:私の知る限りでは、JavaはSSL接続を作成するとき信頼する証明書を探すためにjavax.net.ssl.trustStore
によって参照されるストアだけを使用します。 keysとjavax.net.ssl.keyStore
についても同じです。しかし、理論的には、信頼ストアとキーストアに同じファイルを使用することをお勧めします。
鍵ストアは秘密鍵を保管するためにサーバーによって使用され、トラストストアはアクセスするためにサーバーによって提供される公開鍵を保管するために第三者クライアントによって使用されます。私は本番アプリケーションでそれを行いました。 SSL通信用のJava証明書を生成する手順は次のとおりです。
keytool -genkey -keystore server.keystore -alias mycert -keyalg RSA -keysize 2048 -validity 3950
keytool -selfcert -alias mycert -keystore server.keystore -validity 3950
keytool -export -alias mycert -keystore server.keystore -rfc -file mycert.cer
keytool -importcert -alias mycert -file mycert.cer -keystore truststore