Java SSLSockets:如何拒绝没有证书的客户端

发布时间:2020-07-06 18:30

我有一个客户端和一个服务器,它们通过使用SocketFactory中的SSLSockets连接。配置了密钥库和信任库后,它们可以毫无问题地连接和交换数据。

但是,在编写了一个简单的套接字代码进行测试之后,我意识到服务器正在接受套接字连接并为其创建线程,即使它们不是ssl套接字或它们没有任何证书也是如此。如果他们尝试交换数据,连接将失败,但是服务器仍会为该客户端创建线程。

启动线程的服务器代码如下:

    SSLServerSocket serverSocket = this.configureSSLServerSocket();
    boolean enable = true;
    if (serverSocket !=null) {
        while (enable) {
            try {
                System.out.println("Awaiting connections...");
                SSLSocket sslsocket = (SSLSocket) serverSocket.accept();
                System.out.println("Connection from " + sslsocket);
                new ServerThread(sslsocket).start();
                
            } catch (IOException e) {
                
                e.printStackTrace();
            }
        }
    }

创建套接字的服务器代码如下:

private SSLServerSocket configureSSLServerSocket() {
    
    SSLServerSocket serverSocket = null;
    
    try {
        //Keystore configuration
        KeyStore keyStore = KeyStore.getInstance("JKS");

        keyStore.load(new FileInputStream(this.keystore_path), this.keystore_pass);

        KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        kmf.init(keyStore, this.keystore_pass);

        KeyManager[] keyManagers = kmf.getKeyManagers();
        
        //Truststore configuration
        KeyStore trustedStore = KeyStore.getInstance("JKS");
        trustedStore.load(new FileInputStream(this.truststore_path), this.truststore_pass);

        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(trustedStore);

        TrustManager[] trustManagers = tmf.getTrustManagers();

        //SSL Context configuration
        SSLContext sc = SSLContext.getInstance("TLS");
        sc.init(keyManagers, trustManagers, null);

        SSLServerSocketFactory ssf = sc.getServerSocketFactory();
        
        serverSocket = (SSLServerSocket) ssf.createServerSocket(this.port);
        
    } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException 
            | IOException | UnrecoverableKeyException | KeyManagementException e) {
        
        e.printStackTrace();
        return null;
    }
    return serverSocket;
    
}

客户可以使用以下代码:

      KeyStore keyStore = KeyStore.getInstance("JKS");
      keyStore.load(new FileInputStream(this.keystore_path), this.keystore_pass);

      KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
      kmf.init(keyStore, this.keystore_pass);

        //Truststore configuration
      KeyStore trustedStore = KeyStore.getInstance("JKS");
      trustedStore.load(new FileInputStream(this.truststore_path), this.truststore_pass);

      TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
      tmf.init(trustedStore);

      SSLContext sc = SSLContext.getInstance("TLS");
      TrustManager[] trustManagers = tmf.getTrustManagers();
      KeyManager[] keyManagers = kmf.getKeyManagers();
      sc.init(keyManagers, trustManagers, null);

      SSLSocketFactory ssf = sc.getSocketFactory();
      client = (SSLSocket) ssf.createSocket(server, port);
      client.startHandshake();

基本上,我想拒绝允许的客户端以外的客户端,并在不允许客户端连接或终止威胁的情况下避免创建线程。如果可能的话。

回答1