How to make 'simple SSL' thru Web Services?
Asked Answered
W

5

5

I know how to secure Web Services using certificates. that's my client code:

  SSLContext ssl = SSLContext.getInstance("SSLv3");
  KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
  KeyStore store = KeyStore.getInstance(KeyStore.getDefaultType());
  String password = Configuration.getConfig("keyStorePassword");
  store.load(new FileInputStream(new File(Configuration.getConfig("keyStore"))), password.toCharArray());
  kmf.init(store, password.toCharArray());
  KeyManager[] keyManagers = new KeyManager[1];
  keyManagers = kmf.getKeyManagers();
  TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
  tmf.init(store);
  TrustManager[] trustManagers = tmf.getTrustManagers();
  ssl.init(keyManagers, trustManagers, new SecureRandom());

  HttpsConfigurator configurator = new HttpsConfigurator(ssl);
  Integer port = Integer.parseInt(Configuration.getConfig("port"));
  HttpsServer httpsServer = HttpsServer.create(new InetSocketAddress(Configuration.getConfig("host"), port), 0);
  httpsServer.setHttpsConfigurator(configurator);

  Implementor implementor = new Implementor(); // class with @WebService etc.
  HttpContext context = (HttpContext) httpsServer.createContext("/EventWebService");
  Endpoint endpoint = Endpoint.create( implementor );
  endpoint.publish(context);

Now, how to make 'simple SSL' ? How to make SSL connection without storing certificate on the client side. (Like connecting thru HTTPS in browser)

Wedged answered 25/7, 2011 at 0:12 Comment(0)
T
5

Java Runtime Environment does come with a lots (most widely used) Certificate Authorities in cacerts file. If the certificate you used to secure your service is signed by one of those root CAs, then you need not worry about sharing any certificate with clients.

However if you used self-signed certificate, and you don't want to pass/import certificate in truststore then you can implement custom X509TrustManager and create custom SSLContext for your connections. More details in this blog.

Self-signed certificate are useful for development and test environments but you really should consider getting your server certificate signed from a recognized Certificate Authority like Verisign, Thwate etc.

Torrens answered 25/7, 2011 at 3:1 Comment(4)
I think that TrustAlmostEverythingManager is that what i'm looking for. I'm connecting to server with precise IP (so there is no possibility that someone will spoof). I just want to protect connection from eavesdropping. Am I thinking right? maybe in the future, there will be need to generate client and server certificates.Wedged
Ah...yes but if your web service consumers are outside of your organization, it's a lot more difficult for them to trust self-signed certificate. I would suggest to shell out few bucks upfront to make your clients feel better. I would also suggest to get a proper domain instead of sharing a WSDL with an IP address in it. Self-signed certificates are great for intranet application and test environments but for external clients a few extra bucks will go a long way!Torrens
Clients are outside organization, why trusting is difficult? You mean that it's hard to verify server ? I know that certs from CA would be better, and administrators of this environment know that too. Now, it just don't depend on me. Maybe, in the future, there will be proper certificates (issued by CA) etc.Wedged
Yes - I didn't mean it will be tougher technically. Just that it's difficult for someone to trust a site which presents self-signed certificate especially if web service data exchange has sensitive information. But I sense you are aware of the repercussions already so no worries :-)Torrens
O
2

If I understand you correctly, then you want to have only server-side authentication much in the same way as if you connected to an https site in your browser, without requiring your clients to manage any certificates.

Your clients would connect as usual, simply replacing an http for an https in the connection URL. Java manages its own set of "default trusted root CA authorities" in the form of cacerts, a JKS keystore file located in $JRE HOME/lib/security. If you buy a certificate from any CA whose issuing certificate roots in one of the certificates contained in cacerts, then the client's certificate validation will automagically succeed. Google for "SSL/TLS server certificate" and you will find suitable vendors.

If you would use a self-issued certificate on the other hand, then there's no way to make certificate validation succeed on the client other than importing your self-made certificate in the client's certificate trust store. But that's why a "real" SSL/TLS certificate costs money and your self-issued certificate doesn't - anyone can generate their home-grown certificates, but trusting them is an entirely different story.

Oleaster answered 25/7, 2011 at 2:54 Comment(0)
G
2

You can control if the https server requires client certificates in this way:

HttpsConfigurator cfg = new HttpsConfigurator(sslCtx){
  public void configure(HttpsParameters params) {
        SSLParameters sslparams = getSSLContext().getDefaultSSLParameters();

        // Modify the default params:
        // Using this, server will require client certs
        //sslparams.setNeedClientAuth(true);

        // Using this, server will request client certs. But if not available,
        // it will continue anyway.
        sslparams.setWantClientAuth(true);

        params.setSSLParameters(sslparams);
  }
};
HttpsServer httpsS = HttpsServer.create(new InetSocketAddress(8081), 50);
httpsS.setHttpsConfigurator(cfg);

If client certs are not required, clients can connect without client certificate, so simple calling https will work.

In my blog you can see example of client for how to bypass the server certificate and hostname validation (although not recommended, useful e.g. for testing) http://jakubneubauer.wordpress.com/2011/09/06/java-webservice-over-ssl/

Gameness answered 14/9, 2011 at 9:40 Comment(0)
E
0

Just make the connection with HTTPS. As long as the client is using standard trusted certs it will work just fine. If they have a self signed cert you will need to to import the cert into the java keystore.

Ellmyer answered 25/7, 2011 at 0:15 Comment(3)
I want to make secure WebServices, but I don't want to put any certificate on client machine. I want to connect to server like browser do thru HTTPS. client and server is written by me, I can change it.Wedged
I mean: Simple TLS handshake en.wikipedia.org/wiki/Transport_Layer_SecurityWedged
Browsers have public trusted certs preinstalled into them and so does the Java keystore. They don't negotiate them dynamically...they would not be trusted otherwise.Ellmyer
T
0

HTTPS in browsers works because there is a truststore containing SSL certificates on the client. In other words: There are certificates stored on the client side.

If you want HTTPS without any certificate stored on the client side, I think you should have a look at this article, which explains how to turn off the default certificate validation on HTTPS connection.

Tachistoscope answered 25/7, 2011 at 9:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.