简体   繁体   中英

Java HTTPS Server: Mutual SSL Authentication

I have developed a Java 7 HTTPS server (I use com.sun.net.httpserver.HttpsServer ) for a SOAP web service (mostly influenced by this SO answer ) with the difference that the server is set to need client authentication. This is the server's configuration code I use:

final InetSocketAddress address = new InetSocketAddress( localhost, 8888 );
this.httpsServer = HttpsServer.create( address, 0 );

// ... KeyStore configuration ...

// configure the HTTPS server
this.httpsServer.setHttpsConfigurator( new HttpsConfigurator( sslContext )
{
   @Override
   public void configure(final HttpsParameters params)
   {
      try
      {
         // initialize the SSL context
         final SSLContext c = SSLContext.getDefault();
         final SSLEngine engine = c.createSSLEngine();
         params.setNeedClientAuth( true );
         params.setCipherSuites( engine.getEnabledCipherSuites() );
         params.setProtocols( engine.getEnabledProtocols() );

         // get the default parameters
         final SSLParameters defaultSSLParameters = c.getDefaultSSLParameters();
         params.setSSLParameters( defaultSSLParameters );
      }
      catch ( final Exception e )
      {
         LOG.error( ExceptionUtils.getStackTrace( e ) );
      }
   }
} );

However, upon connections from clients I notice that client authentication is not enforced! I'm currently testing on localhost with self-signed certificates but it seems that any client is able to connect . I tested with SoapUI (which I have not configured to send any certificates to my knowlegde) as well as openssl in client mode with and without a certificate.

openssl s_client -cert client.pem -connect localhost:8888 -debug
openssl s_client -connect localhost:8888 -debug

I have already started the server with the java option -Djavax.net.debug=all but didn't see any relevant parts which indicate a client authentication or a request that the client shall present its certificate. I see that clients validate the server's certificate indeed!

I want to reject any clients which do not present a valid certificate. How can I do this?

After very long searching I noticed that the configure(..) method of the HttpsConfigurator is wrong. I didn't set the SSLParameters correctly!

It should look like this:

@Override
public void configure(final HttpsParameters params)
{
   try
   {
      final SSLParameters sslParams = getSSLContext().getDefaultSSLParameters();
      final SSLEngine sslEngine = getSSLContext().createSSLEngine();
      sslParams.setNeedClientAuth( true );
      sslParams.setCipherSuites( sslEngine.getEnabledCipherSuites() );
      sslParams.setProtocols( sslEngine.getEnabledProtocols() );
      params.setSSLParameters( sslParams );
   }
   catch ( final Exception e )
   {
      LOG.error( ExceptionUtils.getStackTrace( e ) );
   }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM