Get certificate by alias in keystore with multiple entries in Java - java

Ok! We are trying to implement a client server aplication (chatroom) . Of course the server is multithreaded. We wanted the communication to be secure so we used ssl sockets and certificates. I have read that you can store multiple certificates and keys in one keystore. When a client enters the chat he needs to fill in his username.
Do we have to connect the username to the alias of the certificate/key?
If yes, how can we use the specific certificate/key from the keystore from the alias? Or is there another way? I mean how can we "pick" the specific certificate depending on the name
Is there a way for the clients to create their certificates at the time of they enter? (We want the certificates to be signed by a CA we have already implemented)
Thank you!

Basically what you want is Mutual or 2 way SSL. Read these for more information - here and here
In short - the SSL communication works (in context of certificates for authentication) is server will send the certificate to the client and if that certificate is present in the client's certificate store or Java's keystore in your case, then it authenticates the server.
Typically server never asks client to send certificate but in your case you wants it so it makes it Mutual or 2 way SSL. So, while handshake process, server will ask client also to send its certificate and it will also check in its keystore if that certificate is present, if so then it will be happy else it will end SSL handshake.
What you need:
Your each client and your server should have a valid certificate.
Your server should have those client certificate present in its "trust keystore", so that it can authenticate client.
Your each client should have server's certificate in its "trust keystore", so that it can authenticate server.
Your server should be configured to support 2 way SSL. Read here for Weblogic.
Answering your questions specifically:
Do we have to connect the username to the alias of the
certificate/key?
No, only this you want is that client certificate should present in the server's "trust keystore". But since your client app and server is on same machine, so I would recommend that have different JVM's installations to run client and server so that you have support different certificates.
If yes, how can we use the specific certificate/key from the keystore
from the alias? Or is there another way? I mean how can we "pick" the
specific certificate depending on the name
Not applicable.
Is there a way for the clients to create their certificates at the
time of they enter? (We want the certificates to be signed by a CA we
have already implemented)
Certificate should be prepared beforehand, and certificate creation and signing is a complex process, you have to generate a CSR etc.
Please do read my this answer for other details you may require while doing all this.

Related

SSL Configuration for Http Client

this question might sound I bit dummy but I have researched many questions/answers here and can't find the answer for my case.
Currently I am using RestTemplate library to make HTTP requests for my java library that I am currently working on. In order to have successful HTTP call to HTTPS URLs i needed to add a SSL configuration for my HTTP client. Something like this:
clientBuilder
.disableCookieManagement()
.setDefaultRequestConfig(requestConfig)
.setSSLSocketFactory(new SSLConnectionSocketFactory(SSLContexts.custom()
.loadTrustMaterial(null, new TrustSelfSignedStrategy())
.build()));
So this library is supposed to be shipped to the user as a jar executable application and I know that using self-signed SSL certificates is not a good idea for general usage since there might have web servers that do not acknowledge it. I read that If I get a signed SSL certificate then I should save the proper keys on Keystore and also use Trustore to acknowledge the server's certificate. I do not think I can just pass Keystore and Trustore to the client who executes my java library, so my question here is, does Java has a built-in SSL certificate, so I could somehow just do some configuration on HTTP client and the built-in certificates would be used. As far as I know, node.js offers something like that.
Could anyone just give me a explanation of how this works for java spring-boot?
There are two separate certificate verifications that could be happening. To connect to a server using https, you need to receive the server's certificate and validate it using a truststore.
In addition, it is possible for you to have a client certificate, and to pass that to the server so it can authenticate your client. Unless you have been told you need to do that, you don't. Unless the server has been specifically configured to do it, it isn't possible. If it is what you need to do, you need to obtain a client certificate, install it into a keystore and use that keystore in your client.
So for normal https, you do not need a keystore.
Whether you need "TrustSelfSignedStrategy" depends on the server.
If the server has a valid signed SSL certificate, you do not need to do anything special, RestTemplate will just work.
If the server has a self-signed certificate, you need to either configure the client to accept any self-signed certificate, or load the server's certificate into a truststore so the client knows to accept that specific certificate.

Is using a CA certificate enough to communicate securely with an SSLServerSocket?

I have a Java SSL server application and I am able to communicate with its client counterpart using a self-signed certificate and key pair. This is done on my development machine.
Now, the time has come to launch the application on a live server and I have obtained my SSL certificate from an authority (LE).
I can export the signed certificate and import it into a Bouncy Castle keystore for my Android client. However, one thing got me thinking. If the certificate expires it means I'd have to update the application each time. I do not want to do this and it feels like too much work.
I was reading this page and they mentioned (Section Keys for SSL, item number 3) that simply having the CA certificate is enough to establish a connection.
[Optionally] Export the public key certificate of your private key and
distribute it to the SSL parties that will interact with you. (see
section "Export public key certificate from a keystore") If you are
using a certificate from a Certificate Authority then it will be
enough for others to have only the certificate of the Certificate
Authority itself.
I wanted to know how secure this is and what implications are there (if any).
The idea is to avoid recompiling the client application each time the certificate is renewed.
Thanks.
From what I gather, only your client is authenticating your server and not the other way around. This is one way authentication since only one of the two parties is authenticating the other. I could be wrong and you might be doing mutual authentication, but we'll get to that. First let's just consider the simpler case.
In order for your client to authenticate your server, the server needs an SSL certificate with a private key which it seems like you have. This certificate was signed by a CA certificate, which was probably signed by a Root certificate. In order for your client to trust your server, it needs a list of CA certificates which the client trusts to sign an ssl certificate. This list of certificates is your trust store. Your trust store should have the root and the CA certificate for the trusted CA.
If your server's SSL certificate expires, you will need to get a new certificate for your server. If your new certificate was signed by the same CA which signed your old certificate, the client will continue to trust your server without any updates. However, if your new certificate was signed by a CA which is unknown to your client (i.e. the CA certificate is not in the trust store), you will need to update the client's trust store with the CA and root certificates of the new certificate.
This describes one way authentication. However if your application requires mutual authentication, in addition to your client authenticating your server, your server will also need to authenticate your client. The process is exactly the same but in reverse. The client will also need an ssl certificate and the server will also need a trust store with the Root/CA certificates which signed the client's certificate. The same rules apply as when the server authenticates the client. So, if the client's ssl certificate expires and the new certificate is not known to the server's trust store, the trust store must be updated with the new CA's certificate.
One way to get around having to manually update your trust store is to automatically get new trust stores with CAs you trust. This is what your browser does. However, you will still need to update your application if a new certificate is needed.

How Mutual authentication works

I have a java project that requires us to use a mutual authentication certificate. Our code is supposed to communicate with the server with a given ip address
socket = new Socket("00.000.000.000", 0002);
Since the our code is communicating with the remote system:-
If i create a self signed a certificate in my machine(pc) that is not connected to the internet 24/7 will mutual authentication work if i use this cert
If i generate a certificate using Letsencrypt, will will mutual authentication work. I plan to generate the Letsencrypt certificate in my digital ocean droplet.
If i create a self signed a certificate in my machine(pc) that is not connected to the internet 24/7 will mutual authentication work if i use this cert
Only if the peer trusts it. The Internet connection part is irrelevant. You will need to export your self-signed certificate to the peer and have them import it into their truststore.
If i generate a certificate using Letsencrypt, will will mutual authentication work. I plan to generate the Letsencrypt certificate in my digital ocean droplet.
It will work if the peer's truststore trusts LetsEncrypt's certificate.
the underlying issue is, will mutual authentication always work with self signed certificate signed from an ordinary PC
No, see above.
or will it work when signed by a recognized authority
Yes.
In general you should avoid self-signed certificates. They aren't worth the paper they're printed on.

OkHttp SSL Certificate

So i am developing an app which uses a rest connection to a database server. This server uses TLS encryption and has a SSL certificate. Im using OkHttp3.2 to manage my server connection. I can connect to the server without any problems and also encryption works fine.
My question is based on the certificate tester from java's SSL Engine. I can readout everything the Server send about the certificate (Serial, Signature...) but i cant see any information about validation or trust level like a certificate chain.
Does the SSL Engine tests the Certificate independently or do i have to do this manually?
And would OkHttp's certificate pinning do the Job?
And how would i readout the SHA checksum of the certificate like some ssl tester do? e.g. ssllabs.com
So Thanks to Pravin's comment i think i know everything i need.
If someone is intrested a little conclusion of the article:
Android's SSL Engine checkes validity of the Certificate at every Request. The Certificate is compared with trustet root certificates in local system storage (Settings -> Security -> Trusted credentials).
Certificate pinning would add a second security level, in fact it checkes if a certificate in the certificate-chain has a fringerprint which is equal to your setting. Usefull if you would only want to allow a certifiace of a specified provider to communicade with your app.

How can a Java app accepts a server certificate seamlessly?

Most Web browsers that support SSL have a list of CAs whose certificates they will automatically accept. If a browser encounters a certificate whose authorizing CA is in the list, the browser will automatically accept the certificate, and establish a SSL connection to the site.
There is a Java 1.6 client, running on JBoss 7, which is required to make SSL connection to LDAP server. Since the client is on production, if the LDAP server updates its certificate without notifying me to update the certificate accordingly on JBoss, the client will fail. My question is: how can I securely connect(ssl) to LDAP in a similar way the browser “accepts” the certificate seamlessly?
I don’t know if this is feasible in Java. But, any thoughts and feedbacks are all welcome.
Java has a default truststore that contains all the trusted certificates. This is under %JRE_HOME%\lib\security\cacert and has all the trusted CA certificates (Verisign etc).
So if your client https application tries to connect to a server that deploys a certificate signed by these issuers you would have no issue (same as happens with your browser).
Now to your problem. You don't mention enough information about your LDAP server.
I can think of the following:
The LDAP server deploys a certificate signed by some CA (not one of
the known ones).
The LDAP server deploys a self-signed certificate
For case (1) all you need to do is add the certificate of the signer to your truststore (i.e. the certificate of the issure that signed the certificate of your LDAP server). If the LDAP server changes certificate, you would be unaffected provided that it gets the certificate from the same CA which you would have set now as trusted. This trusted certificate could be added in cacerts but the recommended solution is to use your own separate truststore, import it and set it in JVM to override the default cacerts. Plenty of example in Google.
For case (2) this is a really bad setup and are in trouble as you would need to actually update the truststore manually each time the LDAP server changes certificate.
But in any case I can only assume that the certificate changes due to expiration? I can't think of another reason (except compromise of private key but this is not the problem here from your description)

Categories