Java - Public Key Infrastructure implementation in communicator - java

I've a task to write a communicator with PKI. I think about implementation (in Java)of X.509 certificate - I mean SSL/TLS to allow for data/message confidentiality, and message authentication codes for message integrity. All about these I've read in some literature and it's all theoretical. I'm not sure if I think properly. Could anyone, who good understand idea of PKI, give me any advice (for example website where it's good explanation of implementation PKI)?

As ntoskrnl commented, this is hard to do exactly right, even by the experts.
Here is a basic high-level look at the PKI you will need for an SSL connection:
A CA root key and corresponding self-signed certificate.
An intermediate CA key and certificate signed by the CA root key (this
is optional).
A server identity key and certificate signed by either
the intermediate CA or the CA root.
A client identity key and certificate signed by some CA that the server trusts. For your
academic work, you may want this CA to be the same as the one you created. The client identity is only needed if you want to have 2-way (mutual) SSL, where the server authenticates the client.
A web service that is running on something like Tomcat that can be configured for SSL. On the server side, the identity would point to the server key certificate. For 2-way SSL, there would also be a list or keystore of trusted CA certs on the server. Unless a client's certificate was signed by one of those trusted CAs, the server would not allow the client to connect.
On the client side, you would also need a list or keystore of trusted CA certs, and the server's certificate would have to be signed by one of those CAs. The client ID key and certificate and trust keystore would be used by Java when establishing an SSL connection. If you search Stack Overflow, you should find plenty of Java SSL connection examples.
To create the PKI, OpenSSL is a good tool to use. Here is one helpful website:
https://pki-tutorial.readthedocs.org/en/latest/simple/index.html
For a key and its corresponding certificate, you first create a private key, then create a certificate signing request (CSR). The CSR is then signed by a CA key, and becomes a certificate. The certificate contains the public key that corresponds to the private key used to create the CSR.
For MAC, there's a Java example of HMAC here: HMAC-SHA1: How to do it properly in Java?

Related

SSLException: Received fatal alert: certificate_unknow

I have a spring boot backend project.I want to use my ssl cert.
This my application.properties file.
I create robotikg.p12 using with mycert.cert and mycert.key.Also i added mycert.cert in cacerts with using keytool.
When application send the request backend i got this error.I didn't understand where is wrong this config.
When self-signing a certificate or using a self-signed CA (Certificate Authority) to sign your server's certificate, every time you perform a request through another application (be it your own or the browser), you have to tinker with your app (or browser) so that it trusts the connection that is established between itself and the server.
Browsers have their own trust stores (a.k.a key stores) where they keep the trusted certificate chains. Your certificate though, is not signed by any of these trusted certificates.
My approach would be:
Create a CA (self signed)
Sign a Server certificate with this CA
Add the CA to your application's trust store, so that at the moment the TLS handshake is performed, the validation of the server's certificate will be performed against this trust store and thus result valid.

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.

TLS Authentication between Servers and their Keystores Trustores

Before I go to the main question, I do want to state my understanding on Keystore and TrustStores:
1) Keystore - Details of key (private key) using which I would do my authentication as a server
2) Truststore - The list of root/interm CAs and other signed Certificates from different domains which I trust.
I am trying to establish an inter-server authentication and data exchange mechanism. All my servers has FQDN format as myserverX.mydomain.net where X is the index e.g. myserver1.mydomain.net. If my understanding on keystore and truststore is correct, when myserver1 is requesting data from myserver2, it's myserver1 who is client and myserver2 is server.
In this way:
1) myserver1 needs to trust myserver2 so myserver2 public key certificate should be imported into the truststore in `myserver1'.
2) The above will also be true when 'myserver1' is server and myserver2 is client - except now myserver1 public key certificate should be imported into myserver2 truststore.
Am I actually getting things right here? Or is there any fundamental mistake I am making? My intention was to try it out with self-signed certificate, and then, get a proper root CA signed certificate for my servers. But I would be grateful if someone can explain if I am making any wrong assumptions here.
Note - I am going to use Java keytool and JKS-type keystore (with default symmetric key algo and size) and I will use either -certreq and -gencert or -selfcert to generate a self signed certificate for my test.
You have it right but if you use CA-signed certificates the import step is not needed. CAs are already trusted, by definition, and therefore so are the certificates they sign. So your test is pointless.

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.

Java : How setup an SSL One-Way authentification for a server-client over a LAN?

What I need: A secure TLS/SSL communication between a server an a client over a LAN Network. The authentication must be a one way-authentication :
What I have already done: I have created a server and a client which are able to communicate over a Wi-Fi network. I have implemented the SSL sockets but the authentication is missing ... so it won't work :)
Where I need help: I'm a beginner at TLS/SSL, and at network security as well.
Is a CA mandatory or can I "emulate" it ? (It gives the server its certificate, right ?)
Should the server create its own certificate or should I gave one (hardcoded)?
How the client can verify this certificate ?
A CA is not mandatory per se. The alternative to CA-signed certificate is a self-signed certificate, but unless a particular self-signed certificate is explicitly trusted by a client program, authentication (verification) of the peer will fail.
You should create or request a server certificate, and configure the server to use that certificate. The details of how to configure the certificate and other TLS settings depend on what server software or TLS library you are using.
Typically, a client has a collection of trusted root CA certificates. An end-entity certificate is signed either by a root CA, or an intermediate CA which is signed by some superior certificate, all the way up to a root. Servers present a certificate chain of end-entity certificates and any intermediate certificates, up to but (usually) not including a root certificate.
During verification, the client validates that there is a valid chain of signatures down from any of the root CAs it trusts. If so, and provided none of the certificate in the chain are expired or revoked, the server certificate will be accepted and the session will proceed.
Root certificates of public CAs are usually installed and trusted by default in most browsers and operating systems. But you needn't use a public CA; you can create private CA for signing certificates. If you do this, clients will need to be configured to trust its root certificate (details differ by software).
Whether you use a public or private CA, as long as the clients trust the root CA and you have configured the server to present the (chained) server certificate, everything should work!

Categories