I'm writing client for my webapplication, and i signed release jar with my developer certificate, how can i verify that request to rest service was from my signed jar?
You cannot. Signing is for execution validation which means it is on the server side. But you want to check signature on the http/rest request on the client side. Client side has no such validation.
You can add something to the response itself and validate it on the client side but, again, nothing prevents any other server to send the same value and so pretend to be your server.
You can also add some behavior characteristics to your jar (like session cookies) but, again, nothing prevents other jars to emulate it too.
Related
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.
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)
I want to be able to accept both web browser clients and (automated) service clients to a single servlet running in my application. Some of the service clients will authenticate with TLS client certificates, but some will not. I do not want web browser clients to be prompted for a certificate ever, even if the user has some installed in their browser. The decision on whether to prompt for a client certificate is dynamic and based on policy according to the client, so cannot be statically configured in web.xml.
Is there a way to dynamically trigger TLS renegotiation to request a client certificate from within a servlet? If I had access to the raw SSLSocket then I could configure it to require a client certificate and then call startHandshake() to force renegotiation. As far as I can tell, there is no portable way to get hold of the SSLSocket associated with a servlet request/response though.
My application has to run in a variety of servlet containers, so I'd prefer to avoid container-specific solutions if possible. Ideally the solution would not involve a redirect, but I will accept that if it is the only way.
You wrote in comments above:
because that setting will cause a web browser to prompt the user to
choose a certificate if they have one installed that matches one of
the configured CAs. I never want that to happen for web browser
clients
Then I vote for this is impossible to achieve from server side. TLS takes first before any data sent through secure channel. You can't determine is it web browser or not knocking at your door not asking for client identity. From TLS point of view this is just yet another unnamed network client attempts to connect. After secure connection established, data is sent, and you can determine this is browser or not.
You may want to pipe browsers (1 way ssl) and server client (2 way ssl) through different endpoints.
Otherwise you may want to implement you own TLS protocol handshake procedure.
You may want to configure browsers not to answer to client certificate requests instead of configure server not to ask if (if it would be possible) to determine this is browser-based client. May be try to guess it through the cypher suit (list of supported crypto modes) but this is definitely not servlet level of interaction.
I am curious somebody know ho to solve you question.
In HTTPS (SSL) browser send the encrypted data which can be Decrypted by server only.
To confirm it, i did set up the burp proxy on my Firefox browser so that it intercepts the request sent to HTTPS server by browser .
When i receive it at burp, i see the data as entered by user though i was expecting browser must have encrypted that but did not.
So at what point of time browser encrypt data over HTTPS ?
Most pieces of software that do this (e.g. Anti-virus scanners) replace the https certificate with their own so the https traffic can be man-in-the-middled by the software.
While I'm not familiar with Burp, it looks like it does the same: https://portswigger.net/burp/help/proxy_using.html
So instead of
browser --(via https)--> server
Which only the server could read as only the server has the private key to decrypt the http so, it becomes:
browser --(via https)--> burp -- (via https)--> server
If you look at the https cert in your browser you'll probably notice it's been issued by Burp rather than being the real cert that the site shows when not using Burp.
This is the only real way of doing this, without majorly changing the browser to intercept it before the encryption happens, but can create its own problems: Should software really intercept traffic between you and your bank? What if that first connection can be compromised (see the Lenovo superfish incident for example). Many people (myself included) dislike MITM https services for this reason.
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