SSL exception invoking a rest api from Java - java

I see SSL exception while invoking a rest api using Jersey API client library.
This used to work fine till few days ago. Based on the exception, I understand it is certificate expiry related. However I am not sure if the client machine needs to have the certificate (if any) upgraded or the API implementation server needs to upgrade. Code I use to call the API is mentioned below. I verified the ssl certs on my machine using How to determine SSL cert expiration date from a PEM encoded certificate? and I could not find any expired certificates.
com.sun.jersey.api.client.ClientHandlerException: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: timestamp check failed
at com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:151)
Client client = Client.create(JerseyJacksonConfigFactory.getConfig());
this.resource = client.resource(baseUrl);
resource.path("foo").entity(barEntity).type(MediaType.APPLICATION_JSON_TYPE).accept(MediaType.APPLICATION_JSON).put();

Related

Java SSL Certificate Verification with a proxy

I have an Issue with the verification of a ssl certificate.
What I am trying to do, is sending some data from a java program to a server, which then stores that data.
The issue is, that the ssl certificate validation fails with the following exception:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed [...] unable to find valid certification path to...
I am able to resolve this issue, by adding the "end-user" certificate of the server to the truststore I am using.
The chain looks something like this:
Root Certificate 1
Intermediate Cert 11
Intermediate Certificate x
End-User Certificate
Something to note about this whole chain / process:
The communication is using the companies proxy, which replaces all the certificates, and creates its own chain.
So back to the issue:
By adding the end-user certificate everything runs fine. But only for a little while, before that certificate gets refreshed and the one I added is no longer valid. I have tried adding just the root certificate, just each intermediate certificate, adding all 3 certificates and also adding the certificate which would be used if the proxy does not replace the chain. But somehow the certificate cannot be validated.
Is there something I might be overlooking? Do I have to add something else to be able to validate the certificate?
Edit:
Maybe something to note:
I checked the chain, by using the browser and navigating to said server, and then checking the ssl certificates.

Java application show PKIX path building failed when calling external api

My application is running for fetch data from a website with https:
let say
https://api.something.com
When I call with Apache HttpClient using HttpClients.createDefault();
It return the above error show PKIX path building failed.
Even I use Postman to call the api. I still need to disable SSL certification verification to make the call success.
My question is:
Is this is a one way ssl verification? because I don't post data to that domain. I only pull data from it. So server don't have to know who I am. But I can know that's exactly the server I call, and api response is from that domain as well (no middle man). Is my concept correct?
So to resolve this problem, can I just use a dummy sslContext?
thanks a lot
Yes it may be one way TLS but you should have the certificate of CA that issued the certificate of your server in your trust store in java (or other client) to have SSL connection.

Does C# HttpClient ignore SSL certificate errors?

We have an internal web service hosted on https with an authorized root CA. When I tried to call that service from Java Apache HttpClient, it gave me the cert error "PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target".
Using SSL tools, I found out that the web service is sending the cert chain without the intermediate cert and it contains only server cert. So the Java cert error made sense because, only the root CA is present in Java truststore and it is unable to verify the cert chain, hence the error.
But on the other hand, I can call the same web service using C# HttpClient (.Net 4.6.1) without any issues.
Is C# HttpClient ignoring the cert issues with the web service or is it downloading the missing cert? Can anyone please shed some light on this?
Figured this out with very helpful comments from Stephen and Mark. I set up the trace in app.config where I found that C# HttpClient could find the intermediate certificate.
"System.Net Information: 0 : [23580] SecureChannel#41622463 - Remote certificate was verified as valid by the user."
But I had already verified that the intermediate cert wasn't present in Windows cert store which had led to this confusion. I checked there again and turns out the cert was under My User Account and not Computer Account. It must have been installed there when our company desktops were set up.
Now I am not really sure about the difference between the usage of these two cert stores in Windows, but at least I understand how C# client found the cert.

SSLHandshakeException with valid certificate on Tomcat server

I have an Apache web server fronting a Tomcat 8 web server that is running my website, and I'm switching the top-level domain from my.website.ie to my.website.com. I have some code that runs in response to a particular request that generates a PDF. That code fetches an image (using a URL) which is served from the same web server e.g.
Image.getInstance(new URL("https://my.website.com/img/myimage.png"))
In addition to the domain change, I'm also changing my SSL certificate provider to LetsEncrypt (free SSL certs). My development website at the new .com domain is running and the certificate is valid and does not expire for a number of months.
I have another development server running on a separate machine that is still using the .ie domain. The Tomcat codebase running on both of these servers are identical right now. They are both trying to fetch the image at the URL shown above in that particular piece of code.
On the .ie server, the request that generates the PDF works correctly, without any problems fetching the image. On the .com server, the request fails with this error:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
...
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
...
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
My understanding of this error is that the certificate at the target URL is not trusted (e.g. self-signed), but that is not true in this case. Also, both of the servers are hitting the same URL for the image, so why is one server trusting the certificate and the other not?
I haven't made any additional configuration changes on the .ie server that I haven't made on the .com server (with respect to setting up the new certificate), so is there some other (mis)configuration that I haven't considered?
Not trusted means the used CA is not trusted by the software.
Self-signed certificates are never trusted.
Java has it's own trust store (only on Linux the system trust store is used AFAIR?). If the CA certificate is newer than the used Java version it may happen that Java does not trust the CA. Conclusion: Update your Java.
According to this Stackoverflow answer you need at least Java 8u101 for Let's Encrypt support:
Does Java support Let's Encrypt certificates?
The error says that the chain doesn't lead to a root certificate that is trusted. Trusted CA root certificates are stored in Java's root keystore where the root certificate issued by Let's Encrypt is obviously missing.
You can add the root certificate manually to the store or check if newer versions of Java already contain the certificate.

tomcat6 apache cxf javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated

I have a web application using java 7 and tomcat 6 on ubuntu 12.04. It uses apache cxf to make REST calls to a web service on a different server over https. It has been working fine until about 11am today. Then for each REST call whether GET or POST, I receive
javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target errors in catalina.out.
The certificate is in the
jdk/jre/lib/security/cacerts
and does not expire until 2018. When I restart tomcat the program runs fine.
Any idea what would trigger this?
Thanks in advance
Randy
If you are entirely certain that this is not a validity period problem with the service's certificate, here are some more situations to check for:
The certificate on the service side was changed so the one in cacerts is now not doing anything
The certificate you installed was the a system's certificate and you are now connecting to a different node due to load balancing (if so, you would need an intermediate or CA cert)
The service requires Mutual TLS (aka 2-way SSL) and the certificate on your side is now missing or invalid
A host name has changed such that the certificate(s) are no longer valid
Some software or configuration file has changed and now the client and service do not have SSL/TLS versions in common.

Categories

Resources