How to enable ssl in grpc with java using keystore - java

New to gRPC using java and I am not able to find a way how to enable ssl while using truststore and clientstore. I have been able to enable ssl by pointing to individual certificates but not using the truststore. Any leads will be really helpful.

You only need to convert the KeyStore for CA cert (truststore) to a TrustManagerFactory and the KeyStore for client cert/key (clientstore) to a KeyManagerFactory.
The former can be done with
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm();
tmf.init(truststore);
and the latter can be done with
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(clientstore, password);
Then, if you are using Netty transport, you can build the SslContext with
SslContext sslContext = GrpcSslContexts.forClient().trustManager(tmf).keyManager(kmf).build();
See its SslContextBuilder Javadoc.
Lastly, build gRPC channel with
NettyChannelBuilder.forAddress(host, port).sslContext(sslContext).build();
If you are using Okhttp transport, you need to build the SSLSocketFactory with
SSLContext context = SSLContext.getInstance("TLS");
context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());
SSLSocketFactory sslSocketFactory = context. getSocketFactory()
and build gRPC channel with
OkHttpChannelBuilder.forAddress(host, port).sslSocketFactory(sslSocketFactory).build();

Related

How to send given p12 file in post request using java.net.HttpURLConnection (Two way Handshake p12 cert file)

I need to send .p12 file to communicate client-server to send the post request JSON and get the response. I am pretty new to these cert p12 files authentication. Through postman using the p12 file am able to get the response. Now I am trying through the application
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(new FileInputStream("/path/newKeyStoreFileName.jks"), keystorepwd.toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(keyStore, keystorepwd.toCharArray());
KeyManager[] kms = kmf.getKeyManagers();
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(kms, null, new SecureRandom());

How to configure SSLv2Hello with CXF webClient?

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.

Java: establish SSL connection without authentication

I am trying to create an application where I have a server that hosts files and a client that wants to retrieve those files.
I am currently trying to establish a SSL connection between the client and the server, however, I only want the encryption part of SSL not the authentication (I do not want to go through the troubles of creating and managing keystores etc).
All the sample code I have found has used TLS which requires authentication. I was wondering what implementation does not use authentication? I read that there is a Diffie Hellman handshake but I was wondering if there was any other cipher suite besides TLS I could use?
SSLSocketFactory factory = null;
try {
SSLContext ctx;
KeyManagerFactory kmf;
KeyStore ks;
char[] passphrase = "passphrase".toCharArray();
ctx = SSLContext.getInstance("TLS");
kmf = KeyManagerFactory.getInstance("SunX509");
ks = KeyStore.getInstance("JKS");
is there a different SSLContext I could use that will not require me to create a KeyManagerFactory or a Keystore?
If you really want this and you have some other means of avoiding the man in the middle attacks you will now be vulnerable to, just enable the anonymous cipher suites.

Using SSLContext with just a CA certificate and no keystore

I need to setup a javax.net.ssl.SSLContext for use in a Jersey-Client application. All I want to do is the context to accept a custom root ca certificate. Is is really true that there is no way around of generating a keystore file and importing the CA certificate?
Is is really true that there is no way around of generating a keystore
file and importing the CA certificate?
There are way to do it without a keystore file, but since you would have to load the CA certificate you want to trust one way or another, you'll have to load a file or resource somehow.
(You could also certainly implement your own TrustManager that makes all the calls to use the Certification Path API, without using the KeyStore API at all, but that would only increase the complexity of your code, not reduce it. You would also need to understand the Java PKI Programmer's Guide to do this correctly.)
If you really don't want a keystore file, you could use the KeyStore API in memory and load the certificate directly.
Something along these lines should work (not tested):
InputStream is = new FileInputStream("cacert.crt");
// You could get a resource as a stream instead.
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate caCert = (X509Certificate)cf.generateCertificate(is);
TrustManagerFactory tmf = TrustManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm());
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(null); // You don't need the KeyStore instance to come from a file.
ks.setCertificateEntry("caCert", caCert);
tmf.init(ks);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tmf.getTrustManagers(), null);
(Remember to close everything and handle the exceptions.)
Whether loading the certificate this way or loading the certificate into a similar KeyStore instance from a keystore file is more convenient is up to you to decide.

When an SSL cert is renewed, does an Android BKS also need to be updated

So its a simple enough question but I'm not sure of the answer.
Developing SSL on android is a tricky area at times. Most people are left with two options:
* Accept all certificates and risk MITM attacks
* Package the cert as a BKS in the application.
In my apps case, I opted to package the BKS inside and read it through a HttpsURLConnection
KeyStore trustStore = loadTrustStore();
KeyStore keyStore = loadKeyStore();
TrustManagerFactory tmf = TrustManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(trustStore);
KeyManagerFactory kmf = KeyManagerFactory
.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(keyStore, KEYSTORE_PASSWORD.toCharArray());
SSLContext sslCtx = SSLContext.getInstance("TLS");
sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
URL url = new URL("https://myserver.com");
HttpsURLConnection urlConnection = (HttpsURLConnection) url
urlConnection.setSSLSocketFactory(sslCtx.getSocketFactory());
Now I've hit a bump. My certificate is fast expiring and I'm not sure the effect it will have if I upgrade it.
Q: Will renewing the SSL cert without upgrading the app on Android devices stop them from accessing the https URLs?
Q: What are the implications of not upgrading the SSL cert. Will the Android devices not be able to contact the server

Categories