I have written a RestFul web service running on tomcat server and a jersey 2.x rest client for interacting with the service.
The client authentication is being carried out by the method of Certificate-Based Mutual Authentication. I have configured CA certificates at server and I have a client certificate in .PEM format which I am feeding to the java client in Base64 encoded format as
base64encodedCert = new String(Files.readAllBytes(Paths.get("path/to/cert_for_clientA.base64")));
// ClientBuilder
// Client initialization
Response response = target.request().header("X-AUTH-TOKEN", base64encodedCert).accept(MediaType.APPLICATION_XML).get();
The authentication is a custom-token based type i.e.
header("X-AUTH-TOKEN", base64encodedCert).
But this authentication was not working (HTTP error 500?). So I imported the
same client certificate into servers truststore.jks using the keytool -import command and re-deployed the application and the client was successfully authenticated.
The issue is I have to update my server's truststore.jks each time a new client certificate is issued , which isn't the ideal way of doing it.
So , I was wondering if there is a way to avoid such repetitive updates in server's truststore and doing onetime setup for client certificate authentication.
**This is a project on my organizations workspace , we have our own PKI infra for issuing certificates not sure if that is going to make a difference
Related
I have a server as rest API in spring boot and client is Rest Template present in another spring boot application. Currently, in order to enable https,I have configured server.ssl related properties inside application.proeprties file of server like keystore and truststore details. (It's 2Way SSL)
I want my server to reject expired certificate presented by client.Currently, server is not checking validity date of client certificate automatically.
I am using keystore and truststore in jks format.
How to reject expired client certificates??? I am not able to find code.
I am using Spring Security to authenticate using an x.509 certificate, and it works only when the client certificate which is configured in the browser key-store is present in server trust-store.
How it is working currently:
I have configured the SSL client authentication as optional (server.ssl.client-auth=want , like in this post)
I have configured a server trust-store that contains all client certificates. If the certificate presented by the client is in the trust-store, the mutual SSL connection is created.
When I have the client certificate(s) present in the server-side trust-store, Firefox opens a popup with my client-side certificate(s), which I can choose and the mutual SSL connection is established.
I have configured Spring Security to extract the username from the SubjectDN of the client certificate and check it against a UserDetailsService. If a UserDetails object is returned for that username, the authentication process completes successfully
The problem is that if I remove the client-certificate from the server-side trust-store, Firefox doesn't open this popup anymore, and only a one-way SSL connection is made. Even if the Root CA cert is present in the server trust-store.
What I want:
store in the server trust-store only the certificate of a Root Certificate Authority
allow mutual SSL connection when the client presents a certificate issued by the Root CA in the server trust-store (even if the client certificate isn't present in the server trust-store)
I am also intrigued by two resources on the internet. In this tutorial on Baeldung, it says that all client certificates must be stored in the server trust-store for X.509 auth to work (which confirms my experience).
You must remember that for each user that should be verified by the server, its own certificate needs to be installed in the configured truststore. For small applications with only a few clients, this may perhaps be practicable, with an increasing number of clients it may lead to complex key-management for users.
However, this tutorial by #robinhowlett says that
The client will present its certificate in its keystore to the server, and the server will validate the client certificate’s chain using the CA certificate in the server’s truststore.
This is basically what I want to achieve, but am not able to.
Bottom line: did someone manage to store one or more Root CA certificates in the server trust-store and use client certificates issued by these Root CAs to authenticate via X.509 mutual SSL handshake in Spring Security?
I am using Spring Boot 1.5.2.RELEASE (spring-security-web 4.2.2.RELEASE). I have tested my working SSL authentication with Firefox 53.
I found my problem - I was modifying the trust-store (removing the client cert and leaving only the CA cert) while the server was up (Tomcat, in my case). But the trust-store is kept in memory and gets read only once, when the JVM is initialized (details on this ServerFault post). So trust-store changes are not being read during runtime by Tomcat.
So the answer is simple: yes, if only CA certs are present in the trust-store, during the SSL handshake the server communicates to the browser it wants client certificates issued by the trusted CAs and then the browser prompts the user to select a certificate that is issued by a trusted CA (if such a cert is present in the browser keystore).
However, if a CA is added dynamically to the server trust-store while the server is up and running, it won't be detected. The new CA will only be recognized after the server reboots (and the JVM is re-initialized).
Background
I have a .NET console application client that consumes a Java RESTful Service with TLS Client Authentication enabled (aka Mutual Authentication).
It should be the reverse of this SSL Socket between .Net and Java with client authentication
Problem
I am always getting this error: Could not establish trust relationship for the SSL/TLS secure channel
I have no idea how to configure this correctly both on the client and server.
Steps Performed
The .NET console application is already including the CA, intermediate, and server certificates but the same error is being thrown.
I provided the server a Certificate Signing Request (CSR).
The server signed and provided a signed certificate back to me. The signed certificate is being included in the communications between the client and the server. However, the same error is being thrown.
Can anyone enlighten me on how to get a successful handshake?
This has been resolved.
Here are the steps:
Create a Certificate Signing Request (CSR).
Have the CSR signed by the server.
Get the signed certificate.
Include the signed certificate in the HTTP request.
Make sure to put the Self-Signed CA Certificate in the Local Computer's Trusted Root CA store.
Troubleshooting steps in order (do not skip if a certain step is not successful):
Test with HTTP
Test with HTTPS (one-way authentication)
Test with HTTPS (mutual authentication)
I built a Web-Service application in Jdeveloper 11.1.1.7 and deployed it on weblogic 10.3.6 with all Key-store and SSL configuration.
SSl Configuration:
Use Server Certs : Checked
Two Way Client Cert Behavior: Client Certs Not Requested. [That is means it is one-way ssl.
Correct me if that wrong]
SSL Listen Port Enabled: Checked
Key-store Configuration:
Custom Identity and Custom Trust. The file path has been specified for those custom key store
A sample client application has been created and everything seems to be fine; I mean the client can not access the server application without specifying the trust store file location where the server certificate is stored and it is trusted at the client end.
By the server certificate I mean the same certificate that has been configured in server Key-store Configuration
for your information the client application referring to trust store as follow:
System.setProperty("javax.net.ssl.trustStore",[Trust-store location goes here]);
System.setProperty("javax.net.ssl.trustStorePassword", [password goes here]);
Till now nothing wrong. Next is the problem details:
For the purpose of testing I tried to access the deployed web-service application using the SoapUI (open source software). What is confusing is the request has been sent, accepted at the server and proceed without specifying any thing for server certificate nor trust store location in SoapUI project configuration !!
Why the SOAP request has been accepted from SoapUI without referring to server certificate? The request should be rejected in this case.
My experience with SoapUI is that it is quite lenient. For example, if it doesn't check if the CN of server certificate matches the fully qualified domain name in the URL. In your case, your server most likely uses a CA signed certificate. Most of the root and intermediate certificates of well known CA's (e.g. VeriSign/Symantec) are already included in the default truststores for most systems. If your server had used a self-signed certificate, then SoapUI would have incurred SSL error unless you import the self-signed certificates into the truststore of the host where SoapUI is running.
If so, How do you set certificate for authentication, what files do you need? is it .pfx? How would you install that in browser? Been stuck trying to test 2 way ssl through browser. I have a webservice, and trying to connect always returns certification authentication failed.
Expanding on nickrak's answer. 2-way SSL means that the client trusts the webservice, and that the webservice trusts/authenticates the client.
On the webservice side:
Add the client's CA cert into the webservice's trusted certificates. The "CN" in the webservice server certificate must match the URL of the webservice. The webservice server certificate must not be expired. The webservice may choose to do further authentication based on the client certificate...for example, is the client certificate in a "whitelist" of authorized clients. Perhaps the webservice has multiple levels of access, so the client certificate is checked to determine how much access to give the client.
On the client side:
The CA that signed the webservice server certificate will need to be added to the client's trusted certificate list. In a browser, this will be in the "Trusted Root Certification Authorities" section (IE, Chrome) or "Authorities" section (Firefox). The extensions for these certificates are usually .der, .cer, .crt, or .pem. Also, the client's own private key/certificate combination need to be added to the client browser. This will be in the "Personal" section (IE, Chrome) or "Your Certificates" (Firefox). The extensions for these keystores are usually .p12 or .pfx.
Add the client's CA's public certificate to the Trusted Root Certificate Store.
Add the client's public and private key to the browser's Personal Certificate Store. (usually a pfx, but might also be a der/pem/crt/cer.)
Navigate to page requiring certificate
Optionally, depending on browser: select the certificate you want to use for this connection.
Hopefully, success.