TLS で JSSE を使用する Java で。サーバーとクライアントの間に安全なソケットを作成しました。最終的にソケットを安全に接続できるようになった後でも、既存のコードのセキュリティについて根本的な疑問が残ります。私はチュートリアルの指示に従いました。JavaDoc のドキュメントは非常に正確ですが、専門用語のスワヘリ方言を話さない限り、少しあいまいです....
私はかなり長い間 C++ でネットワーク プログラミングを行ってきました。Java への移行は簡単でした。しかし、最近では、トラフィックを安全にすることが賢明であることがわかりました。これは言われています:
Web ブラウザがセキュア ソケットを作成するのと同じ方法でセキュア ソケットを作成したいので、双方向のトラフィックが暗号化されます。クライアントは、サーバーから送信された個人アカウント情報を見ることができ (傍受された場合は非常に悪い)、クライアントは自分のユーザー名とパスワードをサーバーに安全に送信できます (傍受された場合も非常に悪い)。
公開鍵暗号がどのように機能するかについてはすべて知っていますが、公開鍵暗号だけでは副作用があります。公開鍵をクライアントに送信すると、クライアントは公開鍵で暗号化し、サーバーのみが復号化できるデータをサーバーに送信します。私が理解していることから、サーバーは秘密鍵を使用してクライアントに送信されるメッセージを暗号化し、公開鍵を持っている人がそれを復号化できないようにするには、別のセキュリティ層を追加する必要があります。
- ファイルpublic.keyとprivate.keyに保存された公開/秘密鍵のペアがあります(これらはJSSEのkeytoolユーティリティを使用して作成しました
- クライアントに public.key を含めました
- サーバーにprivate.keyを含めました
クライアントクラス:
KeyStore keyStore;
TrustManagerFactory tmf;
KeyManagerFactory kmf;
SSLContext sslContext;
SecureRandom secureRandom = new SecureRandom();
secureRandom.nextInt();
keyStore = KeyStore.getInstance("JKS");
keyStore.load(this.getClass().getClassLoader().getResourceAsStream("server.public"),"public".toCharArray());
tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(keyStore);
kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(keyStore, "public".toCharArray());
sslContext = SSLContext.getInstance("TLS");
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), secureRandom);
SSLSocketFactory sslsocketfactory = sslContext.getSocketFactory();
SSLSocket sslsocket = (SSLSocket)sslsocketfactory.createSocket("localhost", 9999);
サーバークラス:
String passphrase = "secret"
KeyStore keyStore;
TrustManagerFactory tmf;
KeyManagerFactory kmf;
SSLContext sslContext;
SecureRandom secureRandom = new SecureRandom();
secureRandom.nextInt();
keyStore = KeyStore.getInstance("JKS");
keyStore.load(this.getClass().getClassLoader().getResourceAsStream("server.private"),passphrase.toCharArray());
tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(keyStore);
kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(keyStore, passphrase.toCharArray());
sslContext = SSLContext.getInstance("TLS");
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), secureRandom);
SSLServerSocketFactory sslserversocketfactory = sslContext.getServerSocketFactory();
SSLServerSocket sslserversocket =
(SSLServerSocket)sslserversocketfactory.createServerSocket(9999);
/ * ** * ** *質問* ** * ** * * /
すべてが機能します!私はソケットを BufferedReader と BufferedWriter に接続し、accept(); の後で美しくやりとりを始めます。クライアントからの接続を開始し、クライアントとサーバーの送受信ループを開始します。
これで、この時点でクライアントからサーバーへの通信が安全であることがわかりました。クライアントからのトラフィックを復号化できるのは、サーバー キーだけです。しかし、サーバーからクライアントへの通信はどうでしょうか? クライアントの鍵はサーバーからのメッセージを復号化できますが、Public Key Crypto 101 では、クライアントが公開鍵をサーバーに送信することになっていることがわかります。これは、このコードの舞台裏で起こっていますか? SSLContext はこれを処理しましたか? または、クライアントからサーバーへの暗号化された接続が確立されたので、クライアントの秘密鍵と公開鍵のペアも生成する必要がありますか?
上記のコードで送受信されるトラフィックが実際に両方向で安全かどうか教えてください。