Spring Boot SSL Client-Server Communication - java

I am rather new to Spring Boot and SSL. I have developed a SSL rest web server with server keystore, private key, server CA and that correctly handles mutual X.509 certificate authentication. I have tested, that works HTTPS requests with Postman and also Python Client and everything working correctly, both the server and client are successfully exchanging and validating each others certificates.
But my scenario is little bit different,
I have created and connected one Postgresql database to my spring boot application and I have created entities of tables with specific ID numbers and also REST endpoints which you can create, get entity etc.
So my scenario is following;
Python Client comes with specific ID number and makes a request
to one REST Endpoint which is available for everybody (permitted by server).
Spring Boot Server checks that ID number in database and creates a Client Certificate to the Python Client (which I am stucked right now.) and sends this certificate to Client.
After Sending the Client Certificate, Client can use it and communicate Server with Certificate
So question is following;
Is that possible to create a client certificate in runtime in java? If yes, how I can create it and send back to client?
Thank you for your time and response.

I have found the solution. If somebody needs similar solution, you can the following steps;
Create public endpoint in spring boot which you can take the given id number
Compare with your database and if it id number existed call an .sh file (use process)
In this .sh file, use openssl commands to generate a key, remove the passphrase from the key (if you used it), create a client certificate request and finally sign the certificate.
Finally send this signed certificate and private key back to client.
After all, your client can use your signed certificate with private key and use your secured endpoints.

Related

Jetty client / server mutual authentication

I am trying to build a client / server servlet application with these general requisites:
both the client and the server are jetty embedded;
the server expose a servlet in order to receive json data via POST;
the connection must be secured via SSL (i.e. the connection will be done via Internet via https);
I want that only my Jetty client be able to send data to my server, all other tentative must be refused by the server;
the server and the client are unattended machines (i.e. not password via command line could be inserted by human);
no password in clear must be stored on the client device. In general I don't want someone could open the remote client device and stole the password and building a fake remote device capable to send data to my server too.
I have build a perfectly working client / server application via HTTP but I am confused about the security.
I have read that there is the possibility to use client / server mutual authentication and seems what I am looking for but I can't get the complete picture.
In this document client-certificate-authentication there is a more or less clear explanation about how to build a shared trusted CA but the password for accessing the TrustStore and the KeyStore are in clear in the code.
I think I am missing a tile in the puzzle.
Could someone point me in the right direction?
Thanks,
S.
I'm going with a simple answer (for now).
If you just want only your clients to talk to the server, then yes, Client SSL/TLS certificates are the way to go.
You'll want the server's SslContextFactory.Server.setNeedClientAuth(true) set to true. That will in turn cause Java's javax.net.ssl.SSLParameters.setNeedClientAuth(true) to be set on incoming connection establishment. If the client fails to provide the client certificate, the connection is closed, and no HTTP request is sent or processed.
As for securing the client certificate, that's up to you, you can do anything you want to do, as long as it results in a valid client SslContextFactory.Client that the Jetty client can access. This includes ...
Using plaintext passwords
Using obfuscated passwords (minimal effort, minimal security)
Encrypted keystore/truststore passwords elsewhere in your client, provided to the SslContextFactory.Client at the last minute. (modest security, wouldn't be that hard to figure out)
Creating the java.security.KeyStore object yourself and handing it to SslContextFactory.Client.setKeyStore(KeyStore) and SslContextFactory.Client.setTrustStore(KeyStore) methods prior to starting the Jetty Client. (a bit better security wise, puts more work on your behalf)
You might want to consider having the client certificates be short-lived (24 hours?) dynamically refreshed from the server, and have the client certificates be revokable (at the server/CA side) if you encounter abuse. (such as the same client certificate from multiple different client IPs)

Authenticate server to server communication

I am new in authentication/authorization. I need to expose some authenticated apis to be consumed by third parties (server to server). I read how I can do this and figured out that a good option is to use oauth2.
I want to implement this using java with spring boot. My first problem is how to generate client id and client secret. Can you help me with some advice/materials to implement this?
Thanks
For generating the Client-Id and Secret, this guide might be useful.
In all cryptographic affairs, try to find solid / well tested libraries, as mentioned in the article.
Client id and client secret is just a simple login / password pair. Usual constraint apply, just ensure that your secret is not too simple.
As there is only two party implied, the oauth flow is very simple (client credentials).
One server (the client) will consume resources on the other one (the resource server #EnableWebSecurity, #EnableResourceServer) using an access token acquired against the authorizations server beforehand. The resource server may also act as the authorization server (#EnableAuthorizationServer). The client is annotated using #EnableOAuth2Client.
If communication is bidirectionnal, both "server" must be resource server and client (and so have its own client id / secret pair), the authorization server may be independent or hosted by one or both server.

How should I implement SSL?

I have a java client which communicates with python server. Both run within out company intranet. None are exposed to Internet. How I am supposed to ensure that communication happens over SSL?
I have read a lot online and I have come up with following conclusions:
I will generate primary key and certificate to be used by clients and server using java keytool. (creating keystore, private key, certificate and truststore,extracting private key from keystore)
Using private key and certificate inside my python server using SSLSocket class as explained here
Using certificate in truststore inside java client as explained here
I have some doubts:
Are above steps ok?
Above seems to be one way SSL. Should I be doing two way SSL?
Should I be creating shared secret key and communicating using it?
I know this is something related to requirements. But I am in doubt as I am doing SSL first time.
SSL certificates requires validation via (HTTP/HTTPS), I suggest you enable HTTP/HTTPS for the location IP on the router/firewall to allow the validation to go through the internet.
If that is not possible, then you might have to do some local-server SSL validation. By generating a "SELF SIGNED" certificate and registering it manually in both locations.

When to use keystores and when not to?

I have a server side application, that is required to make secured communication with other applications deployed else where. I do have all the information that I need per client(user of my server app) to initiate SSL connection. So, I have client CERT - containing public key, and client private key to be used for SSL and also CA cert that is being used by external application for SSL authentication.
I initiate the SSL connection programatically from within my server application.
So, for every client I create an SSLContext, using an in-memory keystore with all the above imported to it. The various certs and keys are imported programatically using data from my DB. (Note: All of the SSL artefacts are stored in an encrypted manner in DB).
Now my question is that Should I use a physical keystore(A java keystore stored in filesystem) or can I keep all security info in my Database as encrypted blobs.
What is the industry recommended way for the above usecase and why. Any guidelines for the above will be greatly appreciated ...

curl command example with service provider certificate

I have a question on usage of curl command. So basically we are trying to consume couple of third party services have which supports ssl. We have two different vendor's
One vendor has configured their service with ssl which needs a client authentication. For which we had two keys one is private key with public key of ours .we gave our public key to them and we got their public key with certificate.we had a unix client with curl for that we generated the .pem file with the following command "cat server.crt serverpublickey.key > server.pem" and used curl command to call thier service.It worked fine.In this vendor case we never used to get the wsdl from browser. It used to show it needs a client authentication.
We have another vendor which services are configured with ssl but they did not configure with client authentication.So we were able to hit the wsdl link the browser which used to asked us to accept their certificate and we accepted the certificate in the browser and we were able to see the wsdl file. Technically when we hit any site with https:// they send the public certificate and public key .so browser encrypts the data with the key and send back to the server and when we get the data from the server the browser decryption happens with the public key. Now the question is how to call this services from curl ? I guess the previous vendor for every request we send our public key so that they will know it is coming from our side. In the other vendor case they have an authentication service .once we authenticated successfully they are sending us a session id which we need to use for the respective calls. This is the reason why i guess they never had a client authentication configuration with their ssl. Again this is my guess...
"Now my question is for the second vendor we have only the certificate which we got it in the browser. Can some one tell how to call the curl command with the certificate and make call to the third party service "
I might be wrong in some concepts.Any answers to my understanding is also appreciable

Categories

Resources