I want to enable TLSv1.2 as default protocol for clients in jdk7. I can see java 7 supports TLS v1.1, 1.2 but the default enabled is TLSv1.0.
I have gone through some post like this one here which says the client application has to specify in startup scripts which security protocol they want to use or the other way to do this is by java programming.
So is there any way out by which I can chnage the default enabled protocol to TLSv1.2 So that no chnage is required in all the running client application.
This is the code which we are using to initiate SSL connection.
//create the SSLContext with your key manager and trust
//manager, and get your socket factory from the context:
SSLContext ctx = SSLContext.getInstance("SSL");
ctx.init(km, tm, null);
SSLSocketFactory factory = ctx.getSocketFactory();
Change it to this at the entry point of your Main
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(null, null, null);
SSLContext.setDefault(sslContext);
Related
Looking for an example to open HttpsURLConnection with SSLContext and restricted to TLSv1.2. The context is built using trust store and trust key and after I added the custom() call - the TLS setting seem to be changed to just "TLS" vs. "TLSv1.2"
my code is:
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext = SSLContexts.custom()
.loadTrustMaterial(getKeyStore(trustStoreURL, trustStorePassword), new TrustSelfSignedStrategy())
.loadKeyMaterial(getKeyStore(keyStoreUrl, keyStorePassword), keyStorePassword.toCharArray()).build();
So after the custom() I see "TLS" in sslContext properties.
Why do you want to use only a single version, is there any restriction on your server host ? Most modern servers use TLSv1.2 which is backward compatible to one or two versions.
When you use TLSv1.2 while creating socket factory like below,
SSLSocketFactory.getInstance("TLSv1.2")
the default allowed protocols would be SSL, TLS, TLSv1.1, TLSv1.2.
With that being said, to answer your question,
You can set your SSLSocket to enable just a few protocols using the setEnabledProtocols method. Please check this doc for more on this.
Once done, your SSL connection will allow only the specified protocol.
The service provider who is hosting a rest service is asking to communicate using TLS version 1.2 only.
So now I need to make my application to communicate with that service using TLS v 1.2.
I know, in java8 we have an option of disabling the legacy version of TLS and SSL using the property jdk.tls.disabledAlgorithms=SSLv3, RC4 in java.security file.
But in a server there will be other process using the same java settings, so I'm worried like if I change for that property in java.security file, then it will be applicable to other services which are using the same settings.
Question:
I would like to know if there is any other way to make my rest calls use only particular TLS version, through application code using java/spring libraries ?
Create a SSLContext to use the required protocol:
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(null, null, null);
If the client code or library uses HttpsURLConnection then you can set the default SSLSocketFactory for all the HTTS Connections:
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
Or at a per connection level:
HttpsURLConnection urlConnection = ....;
urlConnection.setSSLSocketFactory(sslContext.getSocketFactory());
urlConnection.connect();
Different libraries may have different systems to provide the SSLSocketFactory or SSLContext.
For example, if you are using JAX-RS, you can create a REST client that uses the SSLContext with:
Client client = ClientBuilder.newBuilder().sslContext(sslContext).build();
I'm using CXF to develop REST web services. I have an apache who accept SSL connection using certificate.
I want to test my code with org.apache.cxf.jaxrs.client.WebClient class, but I can't communicate with apache because of:
javax.net.ssl.SSLException: java.lang.IllegalArgumentException:
SSLv2Hello cannot be enabled unless at least one other supported
version is also enabled.
I tried to configure HttpConduit like this:
TLSClientParameters tlsParams = new TLSClientParameters();
KeyStore trustStore = KeyStore.getInstance(KEYSTORE_TYPE);
InputStream inputStream = WesRctAbstractTestcase.class.getClassLoader().getResourceAsStream(KEYSTORE_PATH);
trustStore.load(inputStream, KEYSTORE_PASSWORD.toCharArray());
TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustFactory.init(trustStore);
TrustManager[] tms = trustFactory.getTrustManagers();
tlsParams.setTrustManagers(tms);
tlsParams.setSecureSocketProtocol("SSL");
tlsParams.setDisableCNCheck(true);
httpConduit.setTlsClientParameters(tlsParams);
I don't understand what is missing.
I'm new to SSL and security and I want to build a java client for a web service that uses SSL. the server is properly configured to use two way ssl configuration, but how to build the client..
also if spring has anything for this it will be good..
thanks in advance
You dont have to do nothing special with the client, just use HTTPS on your request instead HTTP.
to get things work you have to create a client keystore and truststore, then define SSLContext with these stores, then instantiate SSLSocketFactory to produce SSLSockets like this:
SSLContext sslcontext = SSLContexts.createDefault();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslcontext, SSLConnectionSocketFactory.STRICT_HOSTNAME_VERIFIER);
CloseableHttpClient httpClient = HttpClients.custom()
.setSSLSocketFactory(sslsf)
.build();
HttpsURLConnection.setDefaultSSLSocketFactory(sslcontext.getSocketFactory());
you should read this http://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/JSSERefGuide.html to understand how it works.
also this question how to write java client and server applications that uses mutual ssl authentication between them? may be useful.
I have to write a Java Client to connect to an SSL server. The server uses openssl certificate, and is configured to do Client Auth.
I can't seem to locate any useful resources online that can help me (who doesn't know anything about openssl and much about SSL) to understand who to go about implementing my Client Side.
Help!
The twist here is that you are using client authentication, so you need a private key and a certificate to identify yourself. You provide this to JSSE by specifying KeyManagers when you initialize an SSLContext.
Customizable Setup
Following are the basic steps. The JSSE API was significantly improved in Java 6, but I'll stick with Java 5, in case you're stuck on that version.
KeyStore tks = KeyStore.getInstance(KeyStore.getDefaultType());
tks.load(...); /* Load the trust key store with root CAs. */
TrustManagerFactory tmf =
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(tks);
KeyStore iks = KeyStore.getInstance(KeyStore.getDefaultType());
iks.load(...); /* Load the identity key store with your key/cert. */
KeyManagerFactory kmf =
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(iks, password);
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
SocketFactory factory = ctx.getSocketFactory();
Socket socket = factory.createSocket(host, port);
System Configuration
An alternative "zero-config" scenario can be used when using the SunJSSE provider. I believe many other providers (like IBM) have followed the same pattern and will work as well. The mechanism uses system properties, and is described in detail by the JSSE Reference Guide.
For client authentication, the important properties are javax.net.ssl.keyStore and javax.net.ssl.keyStorePassword. The values should be the path to the user's key store and the password for that key store's "key entries", respectively.
When using these properties, you can create a new SSLSocket that supports client authentication like this:
SocketFactory factory = SSLSocketFactory.getDefault();
Socket socket = factory.createSocket(host, port);
Since you are using the "default" SSLSocketFactory, which depends on the system-wide properties, all sockets created in the JVM will authenticate with the same certificate. If you need more control than that, you have to use the "Customizable Setup" above.
Java includes SSL support in the standard API. Have a look at these classes in the 1.5.0 javadoc:
SSLSocket if you're doing the comms logic yourself.
HttpsURLConnection if the server side speaks HTTP
You could use httpclient. Have a look at this SSL guide.