0

Javaでネットワーク認証システムを構築しています。接続を SSL で暗号化したいので、SSLServerSocket を使用します。keytool を使用してキーストアを生成しました: (ssl ディレクトリ内)

keytool -genkey -keystore myKeystore -keyalg RSA

次に、サーバークラスで:

System.setProperty("javax.net.ssl.keyStore", "ssl/myKeystore");
System.setProperty("javax.net.ssl.keyStorePassword", "123456");

次に、クライアントで:

System.setProperty("javax.net.ssl.trustStore", "ssl/myKeystore");
System.setProperty("javax.net.ssl.trustStorePassword", "123456");

これは機能しますが、キーストアの作成をクライアントに依存することはできません。

私の目的は SSH のようなモデルです。クライアントはサーバーに送信する秘密鍵を持ち、サーバーは公開鍵を使用してそれを検証します。

キーストアの代わりに単純な RSA キー ファイルを使用できませんか?

4

1 に答える 1

1

ここで多くの側面を混乱させているようです。SSH は SSL/TLS に依存していませんが、これらの概念は実際に広く似ています。

サーバー上のキーストアと一致するクライアントにトラストストアを設定することによって行ったことは、クライアントにサーバーの公開鍵 (証明書内) を信頼させることです。

これは、信頼できるサーバー キーのフィンガープリントをプリロードするのと同等の SSH です。ほとんどの SSH クライアントは、最初の接続を確立するときにサーバーの公開鍵またはそのフィンガープリントを学習します (原則として、このフィンガープリントを手動で確認することを意図しています)。Java で SSL/TLS を使用してこれを実装できます。Andreas Sterbenz の InstallCertはそうです。

これの目的は、クライアントがサーバーの ID を検証できるようにすることです (これがないと、MITM 攻撃が可能になる可能性があります)。

クライアントはサーバーに送信する秘密鍵を持っており、サーバーは公開鍵を使用してそれを検証します。

クライアントが秘密鍵 (実際には使用しますが、サーバーに送信することはありません) を持っている場合、それはクライアントの認証にのみ使用されます。これの目的は、サーバーがクライアントの ID を検証できるようにすることです (たとえば、パスワード認証の代わりとして)。

これは、クライアント証明書認証を使用して SSL/TLS でも実行できます。

これらすべてにおける SSH と SSL/TLS の主な違い (プロトコルは別として) は、SSL/TLS は X.509 証明書 (公開鍵と、エンティティの ID を記述する追加の属性を含む) を使用する傾向があるのに対し、SSH は生の公開鍵を使用する傾向があることです。直接。(X.509 証明書を使用するための SSH の拡張もありますが、あまり一般的ではありません。)

どちらの場合も、クライアントは MITM 攻撃を防ぐためにサーバーの ID を確認する必要があります。これは、公開鍵インフラストラクチャ (および X.509 証明書) を使用して SSL/TLS でより慣習的に行われますが、SSH のように、最初の接続時に鍵を学習することもできます: これにはより多くの作業が必要です (カスタムの信頼マネージャーが必要になります)。 . (制御された環境での) 妥当な妥協案は、サーバーの証明書がプリロードされたクライアントのトラスト ストアを使用することです。これは、サーバーの秘密鍵を決して渡してはならないことを除いて、多かれ少なかれすでに行ったことです。 サーバーのキーストアには秘密鍵が含まれているため、ここで同じキーストアを使用しないでください。代わりに、証明書のみをエクスポートし、反対側で信頼ストアとして使用するキーストアにインポートします。

于 2013-02-24T22:32:31.390 に答える