Java 没有密钥库的TLS连接
即使密钥库文件(下面的sessionKeyStore)为空,我的客户端程序如何能够创建SSLSocket并成功连接到服务器程序,这让我感到困惑 下面的代码将成功创建一个具有空密钥库的TLSv1.2套接字,并成功地与我的服务器程序握手,我认为这总是需要密钥交换Java 没有密钥库的TLS连接,java,sockets,ssl,tls1.2,Java,Sockets,Ssl,Tls1.2,即使密钥库文件(下面的sessionKeyStore)为空,我的客户端程序如何能够创建SSLSocket并成功连接到服务器程序,这让我感到困惑 下面的代码将成功创建一个具有空密钥库的TLSv1.2套接字,并成功地与我的服务器程序握手,我认为这总是需要密钥交换 TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); tmf.init(sessionKeyStore); // sessionKe
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(sessionKeyStore); // sessionKeyStore IS NULL!!
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(sessionKeyStore, SSL_PASSWORD.toCharArray()); // password is not null
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
SecureRandom sc = createSecureRandom();
sc.setSeed(System.nanoTime());
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), sc);
SSLSocketFactory factory = sc.getSocketFactory();
SSLSocket socket = (SSLSocket) factory.createSocket(server, serverPort);
((SSLSocket) socket).startHandshake();
我没有意识到客户端身份验证不包括在基本的TLS握手中。只有服务器经过身份验证。客户端身份验证是一种单独的握手,在服务器首次身份验证后发生,并且仅在服务器请求时发生。问题是我需要特别告诉服务器套接字要求在TLS握手中包括客户端证书验证。在Java JSSE中实现这一点的方法是向服务器端添加以下代码:
SSLContext sslContext = getSSLContext();
SSLServerSocketFactory sslserversocketfactory = sslContext.getServerSocketFactory();
SSLServerSocket sslserversocket = (SSLServerSocket) sslserversocketfactory.createServerSocket(port);
// Add the below to force a certificate request on the client.
sslserversocket.setNeedClientAuth(true);
只有在服务器请求客户端证书时,客户端才需要密钥库。密钥存储在文件系统中,而不是类路径中。