在 Java 中使用 JSSE 和 TLS。我在服务器和客户端之间创建了一个安全套接字。在最终让套接字安全连接之后,我仍然对现有代码的安全性有一个基本问题。我按照教程中的说明进行操作,有时 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(); 之后开始来回漂亮地交谈;从客户端连接并启动我的客户端和服务器发送/接收循环。
现在我知道此时客户端到服务器的通信是安全的。只有服务器密钥可以解密来自客户端的流量。但是服务器到客户端的通信呢?客户端的密钥可以解密来自服务器的消息,但在公钥加密 101 中,您了解到客户端现在应该向服务器发送公钥。这是在这段代码的幕后发生的吗?SSLContext 是否解决了这个问题?或者现在我有一个从客户端到服务器的加密连接,我现在是否也希望为客户端生成一个私钥/公钥对?
让我知道上述代码中发送和接收的流量是否在两个方向上实际上都是安全的。