Setting up SSL in Java 6 (GlassFish 3 server) - java

We have a Java web application running inside GlassFish 3 web server.
Our application connects to a LDAP server for authentication. Now customer is running LDAP on SSL i.e ldaps.
So we fetched the certificate from their LDAP server and added it to our trusted certificate. But still we sometime gets:
exception is 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]
Further investigation by LDAP admin, his words:
"We added additional servers behind the load balancer. If they
trust just the server CERT instead of the CA then you would be
experiencing this problem. They should trust the CA or should not
perform any certificate validation"
Which means that there are many LDAP server running behind the load balancer and each server has different certificate, and we just trust on one particular certificate.
Now the resolution they say is to trust on the CA and not on individual certificate.
NOW at this point I am confused!
Is it the case that we can get a CA certificate and trust on it so that any certificate issued by that CA will be automatically trusted..
If so how to do that?
Will the CA certificate be fetched from the LDAP server or do we have to ask for it?
Or have I created a wrong mind model for this or is there a concept missing?
Also what is "trusted root certificate"?

What they are saying is that the servers are signed using a common CA (like Verisign, Thwate etc). All you need to do is trust that CA (you do this by importing the CA's trusted root certificate).
You will need to find out which CA is being used and then check your cacerts file to see if you already trust the CA (apparently you dont since you are receiving the error). There a number of ways you can find out the CA being used but you can simply ask your LDAP admin which CA is being used. Some companies also use a local CA and this could very well be how your ldap servers are setup.

Related

Wildfly does not pass intermediate certificate to HTTPS client

So I have this certificate chain made of 3 certificates:
Root cert (installed in all clients)
Intermediate cert (installed in my browser, but not in other clients/Java apps accessing webservices)
Domain wildcard certificate
Wildfly is configured to use a keystore that holds intermediate and domain certificates in JKS format, along with the private key for the domain cert. When I send a HTTPS request from my browser, the certificate is validated just fine and everything seems OK. But when the Java client application I am working on tries to establish a connection, it cannot build a valid certificate chain:
javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
I checked the certificates delivered by Wildfly using openssl (openssl s_client -showcerts -connect <servername>) and confirmed that the intermediate certificate is NOT transmitted even though it is present in the keystore. Now I can work around this in my development environment by adding the intermediate cert to my local trust store, however that is not an acceptable long-term solution for production.
In my Wildfly's standalone.xml I have specified the keystore and the alias of the wildcard certificate.
<server-identities>
<ssl>
<keystore path="/path/to/keytsore.jks" keystore-password="supersecure" alias="*.redacted.com"/>
</ssl>
</server-identities>
Searching through the Wildfly admin docs I saw no mention of intermediate certificates. I tried to add an additional element to the config (same path and password, but alias of the intermediate certificate), but Wildfly would not start up with that.
Any idea how I can get Wildfly to present the intermediate certificate to connecting clients? Does it need to have a specific alias name? Or is there another way to tell Wildfly the alias of any intermediate cert?

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!

Debian SSL certificates ERROR: cannot verify xxx certificate / javax.net.ssl.SSLHandshakeException

I have a strange problem (it's 100% server configuration problem,) for example I want to download something from Dropbox:
Resolving dl.dropboxusercontent.com... 23.23.160.146, 50.17.227.107,
54.221.248.69, ... Connecting to dl.dropboxusercontent.com|23.23.160.146|:443... connected. ERROR:
cannot verify dl.dropboxusercontent.com’s certificate, issued by
“/C=US/ST=CA/O=SonicWALL Inc./CN=SonicWALL Firewall DPI-SSL”:
Self-signed certificate encountered. To connect to
dl.dropboxusercontent.com insecurely, use ‘--no-check-certificate’.
Yes, I know that I can use --non-check-certificate but when I want to use SSL connection in Java app I have something like this:
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
This app works great in other servers or in local machines, any ideas what is wrong here?
/C=US/ST=CA/O=SonicWALL Inc./CN=SonicWALL Firewall DPI-SSL
Your traffic is visibly intercepted by a deep packet inspection firewall that acts as a MITM proxy to monitor your traffic.
This can generally be thought of as "legitimate" MITM attacker. (However legitimate this may be depends on a number of legal and ethical aspects.) Your local network administrator should be able to tell you a little bit about this. If this is part of a company network, this company is monitoring your traffic, including the contents of your HTTPS connection (so it's no longer secure from end-to-end). It the firewall does its job properly, it should still secure the connection from the firewall to the server (It's probably hard to know whether it check certificates properly.)
In general, such a firewall or proxy acts as its own Certification Authority, effectively forging each certificate as requested.
Most clients on the corporate network would trust certificates it issues (like the one you're facing) because system administrators would also install the CA certificate as a trusted certificate into each machine within that network. You probably have it the OS trusted root certificates.
However, it is likely that network administrators did not install this CA certificate into your JRE installation (which uses its own set of trust anchors by default).
Try to export that CA certificate (see the name above) from a reference machine and import it into the truststore you're using (either your JRE's default truststore: cacerts or a new truststore you build and pass to your application via the javax.net.trustStore properties).
Typically, you can use something like this (assuming you've exported the Firewall's CA as "firewallca.pem"):
keytool -import -file firewallca.pem -alias firewallca -keystore truststore.jks
If the truststore.jks file doesn't exist, it will be created. Otherwise, you can take a copy of the cacerts file in the lib/security directory of your JRE. You can also do this directly on the cacerts file (using -keystore /path/to/truststore.jks, provided you have write access to it).
If you choose not to do it on the default truststore (that cacerts file) but use a local truststore like truststore.jks, you'll can use it by using this system property when running your application: -Djavax.net.trustStore=/path/to/truststore.jks
For other ways of configuring your truststore, check this answer.
Another way to fix this is to tell Java to use your OS's truststore. I'll assume you're using Windows here. Using these system properties should work:
-Djavax.net.trustStore=NONE -Djavax.net.trustStoreType=WINDOWS-ROOT
(Try with WINDOWS-MY instead of WINDOWS-ROOT if this doesn't work.)
The WINDOWS-MY/WINDOWS-ROOT is a bit buggy in that it will miss some of the certificates in the Windows store: it uses the certificate "friendly name" (non unique) as the keystore alias (unique), so a certificate with a given friendly name will hide the others with the same name. (This effectively reduces the number of CA certificates that are trusted unfortunately.)
Since you're in an environment where presumably all the traffic goes through your DPI firewall, you'll probably only ever have to use one CA certificate at most. As long is it doesn't share its "friendly name" in the Windows list with any other cert, you should be fine.
You need to add the server's SSL certificate in your client's Java keystore. Take a look at this SO post:
Resolving javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed Error?
TIP: This is because your client's JVM does not 'trust' the server's SSL cert. So you need to add the cert in your keystore.

Why a root certificate is not trusted by java client, even though it is already in the cacerts key store

I am experiencing an issue when calling web service in my java project. The web service client is running in an java ee application deployed in WebSphere 7. The SSL certificate chain is having the root certificate of Go Daddy Class 2 Certificate Authority. and I do see it in the cacerts file under the WebsPhere JVM folder, but I am keeping getting untrusted certificate error:
java.security.cert.CertPathValidatorException: The certificate issued by OU=Go Daddy Class 2 Certification Authority, O="The Go Daddy Group, Inc.", C=US is not trusted; internal cause is:
java.security.cert.CertPathValidatorException: Certificate chaining error
Cant figure out why getting this error, and how I can resolve this issue. Please help me.
The web service is running in Server A, The client works well when I run it on my machine, the cacerts on my machine includes that root certificate.
When the client get deployed with an web application onto Server A, it doesn't work. We checked the cacerts file, it does include the go daddy root certificate.
When the client and webservice get deployed onto some other envs running with VeriSign certificate chain, it works as well.
Thanks
In my opinion, the CA root public key should be added to your trust store as you are using your server it as a webservice client and not a webservice server.
On your admin console, you should have:
Security->SSL certificate and key management->Key stores and certificates-> NodeDefaultTrustStore-> Signer certificates
Chaining error
You haven't imported the chain correctly, or there is something wrong with it. I use GoDaddy certificates and I don't get chaining errors, so it is more likely the former.

How can a Java app accepts a server certificate seamlessly?

Most Web browsers that support SSL have a list of CAs whose certificates they will automatically accept. If a browser encounters a certificate whose authorizing CA is in the list, the browser will automatically accept the certificate, and establish a SSL connection to the site.
There is a Java 1.6 client, running on JBoss 7, which is required to make SSL connection to LDAP server. Since the client is on production, if the LDAP server updates its certificate without notifying me to update the certificate accordingly on JBoss, the client will fail. My question is: how can I securely connect(ssl) to LDAP in a similar way the browser “accepts” the certificate seamlessly?
I don’t know if this is feasible in Java. But, any thoughts and feedbacks are all welcome.
Java has a default truststore that contains all the trusted certificates. This is under %JRE_HOME%\lib\security\cacert and has all the trusted CA certificates (Verisign etc).
So if your client https application tries to connect to a server that deploys a certificate signed by these issuers you would have no issue (same as happens with your browser).
Now to your problem. You don't mention enough information about your LDAP server.
I can think of the following:
The LDAP server deploys a certificate signed by some CA (not one of
the known ones).
The LDAP server deploys a self-signed certificate
For case (1) all you need to do is add the certificate of the signer to your truststore (i.e. the certificate of the issure that signed the certificate of your LDAP server). If the LDAP server changes certificate, you would be unaffected provided that it gets the certificate from the same CA which you would have set now as trusted. This trusted certificate could be added in cacerts but the recommended solution is to use your own separate truststore, import it and set it in JVM to override the default cacerts. Plenty of example in Google.
For case (2) this is a really bad setup and are in trouble as you would need to actually update the truststore manually each time the LDAP server changes certificate.
But in any case I can only assume that the certificate changes due to expiration? I can't think of another reason (except compromise of private key but this is not the problem here from your description)

Categories