SSL Error: unable to find valid certification path to requested target - ssl

I am trying to connect to a url through my server that requires certificate. I have imported my Client Authentication Certificate to {JAVA_HOME}/jre/bin/security/cacerts and also i have placed it in the keystore in Jboss/bin and jboss/server/conf/ then i restarted my server and it is still giving me the folowing error.
Caused by: java.io.IOException: Could not transmit message
at org.jboss.ws.core.client.HTTPRemotingConnection.invoke(HTTPRemotingConnection.java:265)
at org.jboss.ws.core.client.SOAPProtocolConnectionHTTP.invoke(SOAPProtocolConnectionHTTP.java:71)
at org.jboss.ws.core.CommonClient.invoke(CommonClient.java:340)
at org.jboss.ws.core.jaxws.client.ClientImpl.invoke(ClientImpl.java:290)
... 40 more
Caused by: org.jboss.remoting.CannotConnectException: Can not connect http client invoker after 1 attempt(s)
at org.jboss.remoting.transport.http.HTTPClientInvoker.makeInvocation(HTTPClientInvoker.java:249)
at org.jboss.remoting.transport.http.HTTPClientInvoker.transport(HTTPClientInvoker.java:161)
at org.jboss.remoting.MicroRemoteClientInvoker.invoke(MicroRemoteClientInvoker.java:165)
at org.jboss.remoting.Client.invoke(Client.java:1724)
at org.jboss.remoting.Client.invoke(Client.java:629)
at org.jboss.ws.core.client.HTTPRemotingConnection.invoke(HTTPRemotingConnection.java:243)
... 43 more
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
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1611)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:187)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:181)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1035)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:124)
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:516)
at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:454)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:884)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1112)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1139)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1123)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:434)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:904)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:230)
at org.jboss.remoting.transport.http.HTTPClientInvoker.getOutputStream(HTTPClientInvoker.java:1214)
at org.jboss.remoting.transport.http.HTTPClientInvoker.useHttpURLConnection(HTTPClientInvoker.java:334)
at org.jboss.remoting.transport.http.HTTPClientInvoker.makeInvocation(HTTPClientInvoker.java:231)
... 48 more
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:294)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:200)
at sun.security.validator.Validator.validate(Validator.java:218)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:126)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:209)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:249)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1014)
... 62 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:174)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:238)
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:289)
... 68 more
I want to ask what can i do to fix it? Do i need to put another one of these in server.xml for this certificate:
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150"
scheme="https" secure="false" strategy="ms" address="${jboss.bind.address}"
keystoreFile="${jboss.server.home.dir}/conf/.keystore"
keystorePass="changeit" sslProtocol="TLS"
truststoreFile="/usr/lib/jvm/java-6-sun-1.6.0.10/jre/lib/security/cacerts"
truststorePass="*****"
SSLImplementation="org.jsslutils.extra.apachetomcat6.JSSLutilsImplementation"
acceptAnyCert="true" clientAuth="want" />
or am i making anyother mistake?

I know you said you already imported the certificate, but take a look at these steps to see if you missed a step somewhere:
Here's an overall summary of how to import certificates to fix the following error:
Error while trying to execute request.
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
How to import certificates
Go to URL in your browser, click on HTTPS certificate chain (little lock symbol next to URL address) to export the certificate
Click "more info" > "security" > "show certificate" > "details" > "export..".
Save as .der
Repeat for any certificates you need to import
Locate $JAVA_HOME/jre/lib/security/cacerts
Import all *.der files into the cacerts file using the following:
sudo keytool -import -alias mysitestaging -keystore $JAVA_HOME/jre/lib/security/cacerts -file staging.der
sudo keytool -import -alias mysiteprod -keystore $JAVA_HOME/jre/lib/security/cacerts -file prod.der
sudo keytool -import -alias mysitedev -keystore $JAVA_HOME/jre/lib/security/cacerts -file dev.der
The default keystore password is 'changeit'
You can view the change that you made with this command that shows the Certificate fingerprint.
keytool -list -keystore $JAVA_HOME/jre/lib/security/cacerts
If this doesn't solve the problem, try adding these java options as arguments:
-Djavax.net.ssl.trustStore="$JAVA_HOME/jre/lib/security/cacerts"
-Djavax.net.ssl.trustStorePassword="changeit"

For SSL Web service configuration we must make this steps:
1) insert CA certificates into a keystore you can put this to JVM or put this into the jre security directory, or you can import to the jre default keystore.
2) import authentification certificate with a key into the keystore (it might be java keystore or another one). keystore can be jks too, not only pkcs12. I have tested and jks works well too.
3) Tell JVM that you need that keystore - when we are starting Jboss. It can be something like this (in my case it looks like this):
> "-Dprogram.name=JBossTools: JBoss 4.0 CLONE OF ESS SERVER" -server
> -Xms256m -Xmx512m -XX:MaxPermSize=256m -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 "-Djava.endorsed.dirs=..\jboss-4.0.2\lib\endorsed"
> "-Djavax.net.ssl.keyStore=../Java/jdk1.6.0_45/jre/lib/security/cacerts"
> "-Djavax.net.ssl.keyStorePassword=changeit"
Also certificates can be der encodded or base 64. it means that you might need to convert certificates with open SSL and etc. Also another problem is that sometimes convertation might cause problems, so you can use such a script for more easy and flexible convertations.

I was facing this issue because of the disabled TLSv1.2 protocol. I have solved it by adding TLSv1.2 in VM arguments. Below are the steps to enable protocol
You need to add this line in vm arguments -- > -Dhttps.protocols=TLSv1.1,TLSv1.2
Go to servers tab in eclipse >> double click on wildfly >> Open launch configuration >> paste above line in vm arguments in the end.

If it is a client certificate, then you need to put it in your truststore; if it is a server certificate then it goes in your keystore. Also, in case your certificate has intermediate CA Certificates, you need to add them too.

Related

JMeter Ignore SSL Security Certificate

I am getting the following error while trying to connect to LDAP Server.
Is there a way to Ignore SSL Security Certificate. I am able to connect to the server outside of JMeter using other tools.
Thread Name: Thread Group 1-1
Sample Start: 2018-09-23 12:16:48 EDT
Load time: 154
Connect Time: 0
Latency: 0
Size in bytes: 555
Sent bytes:0
Headers size in bytes: 0
Body size in bytes: 555
Sample Count: 1
Error Count: 1
Data type ("text"|"bin"|""): text
Response code: 800
Response message: javax.naming.CommunicationException: x.x.x.x:1636
[Root 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]
Response headers:
SampleResult fields:
ContentType: text/xml
DataEncoding: UTF-8
the best (and most common) way to solve this is to trust the LDAPS server, i.e. add the server's certificate to JRE's cacerts file using keytool. There is already an s-o answer on how to do this (here: Is there a java setting for disabling certificate validation?) - the gist is (taken from there)
cd %JRE_HOME%
keytool -alias REPLACE_TO_ANY_UNIQ_NAME -import -keystore ..\lib\security\cacerts -file your.crt
When you don't have the public key (certificate file) yet, you can e.g. get it by connecting to the LDAPS server with Apache Directory Studio (https://directory.apache.org/studio/) which stores all public keys of LDAPS servers you trust. The exact routine was described on the mailing list already (here: http://mail-archives.apache.org/mod_mbox/directory-users/201004.mbox/%3C4BBF6471.6040900#apache.org%3E), so I'm just giving the gist (again largely taken from there)
find ~/.ApacheDirectoryStudio -name \*.jks # gives you the keystores managed by DirectoryStudio
keytool -list -keystore path/to/permanent.jks
keytool -exportcert -alias <aliasname> -keystore path/to/permanent.jks -file your.crt
Most probably it indicates the issue with your LDAP server SSL setup, i.e. one of certificates in chain cannot be checked against authority. I would recommend double-checking the certificate chain using i.e.
OpenSSL tool like: openssl s_client -showcerts -connect yourhost:yourport
SSLPoke tool like: java -Djavax.net.debug=ssl SSLPoke yourhost yourport
You have 2 ways:
Add the certificate into the JVM truststore like:
keytool -import -file your_ldap_certificate -alias certificate -keystore trustStore.keystore
Create a custom class which will be trusting all the certificates and set java.naming.ldap.factory.socket system property to point to that class (the class must be in the JMeter Classpath)
Just in case if you need more information on LDAP servers performance testing with JMeter check out How to Load Test LDAP with Apache JMeter™ article.

SSL certificates in Codename One using Simulator

I created a custom SSL certificate through Java keytool command, in order to test the connection from my Codename one app and my HTTPS REST web service.
This is the complete command:
keytool -genkey -alias my_alias -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 3650
When the app (running on the simulator) tries to interact with the web service, it returns the following exception:
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
I read here
and I understood for a real mobile device is possible to add the custom certificate.
My question is: using the simulator, how can I do? How can I use my "home-made" certificate?
There is really no reason to do this anymore. You can but if you just don't want to pay for a certificate you can just use "lets encrypt" and it will work: http://letsencrypt.org/
Notice that it requires a recent version of JDK 8 (I think 128 or newer).
SSL will only work with proper domains and not with IP addresses etc.

Glassfish Admin Console stopped after change keystore.jks

I use GF 3.1.2.2 and now I need to configure a Lets Encrypt SSL certificate for my webapp. After I changed the default keystore.jks with the new including the Lets Encrypt cert, my webapp worked fine, but Admin Console no.
The server.log file arises this error because it needs the default keytore.jks file:
[#|2016-05-17T11:31:15.344-0400|SEVERE|glassfish3.1.2|org.glassfish.admingui|_ThreadID=72;_ThreadName=Thread-2;|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;
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;
restRequest: endpoint=https://localhost:4848/management/domain/anonymous-user-enabled
attrs={}
method=GET|#]
I am 3 years late, but who knows maybe someone reads it anyway :)
The reason for your problem is that the certificate the admin-listener uses, is not within your new keystore.
The default certificate the admin-listener (Port 4848) uses has the Alias-Name 's1as' and is provided with the Glassfish installation.
This certificate is within the Default-Keystore keystore.jks.
If you changed the keystore with a new one, then Glassfish can't find the certificate he uses for the admin-listener.
This is most probably the solution to your problem:
Easy one:
Stop glassfish
Go to domain.xml in Path ./glassfish/glassfish/domains/domain1/config and whereever you find an attribute with the name 'cert-nickname' change the value to the Alias-Name of your Let's Encrypt Certificate.
Restart Glassfish
Harder but more sophisticated:
Find out which certificate your admin-listener used before.
For that temporarily change back to your old keystore.jks.
Login into the
Admin console and go look for the Certificate NickName under
/Configurations/server-config/Http-Service/Http-Listeners/admin-listeners.
The default certificate Glassfish uses has the Name s1as.
a) If its a fresh Glassfish installation and the admin-listener still uses the default certificate s1as then i would suggest you switch over to your new Certificate.
Just change the Certificate NickName to the Alias-Name of your Lets' Encrypt certificate and click the save button.
Stop Glassfish
Switch over to your new Keystore
Start Glassfish
b) If you insist on keeping the old certificate then you have to extract it from your 'old' keystore via keytool and import it into your new keystore.
Stop Glassfish
Extract the old certificate with this command:
keytool -export -alias myOldCertificateNickname -keystore keystore.jks -file myOldCertificate.crt
Replace myOldCertificateNickname with the Certificate NickName you found in Step 1!
Import your freshly exported old certificate into your new keystore
keytool -import -alias myOldCertificateNickname -file myOldCertificate.crt -keystore myNewKeystore.jks
Start Glassfish
Now this is most important!!
For all this to work you need to know the password for both keystore's and the certifcates as well! And the MasterPW of Glassfish too!
Because Glassfish insist that all 3 Passwords have to be the same (MasterPW, Keystore Password, Password for the certificate)
And here a really good online guide for Installation of certificate in Glassfish
https://www.ssls.com/knowledgebase/how-to-install-an-ssl-certificate-on-glassfish/

Spring security, ssl ldap and no certificate

I use spring security to manage login. I've configured spring security to connect to a ldap server which is securized with ssl (ldaps).
This server is a test server and has no valid certificate. When I try to test the login, spring security complains that the certificate cannot be verified (of course!):
sun.security.validator.ValidatorException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException: unable to find
valid certification path to requested target
My question is simple : I don't want to manage any kind of certificate, I would like to deactivate the certificate check and keep using a ssl ldap. How can I do that ?
It sounds like the certificate of the LDAP server is just self-cert rather than invalid.
To me the simplest solution would be to get that certificate and add it to the cacerts trust store in java. Once that's done the code will run without any modifications.
To get the certificate from the server:
$ openssl s_client -showcerts -connect ldapserver:636
The output will contain a number of entries delimited with
-----BEGIN CERTIFICATE-----
aklfhskfadljasdl1340234234ASDSDFSDFSDFSDFSD
....
-----END CERTIFICATE-----
Copy the last certificate entry into a file (ldapca.crt)
Then, add it to the java keystore in $JRE_HOME/lib/security
$ cd $JRE_HOME/lib/security
$ keytool -import -alias ldapca_self_sign -keystore cacerts -storepass changeit -file ldapca.crt
That means, you'll trust the certificate on the LDAP server and are using SSL correctly in your test environment (rather than having some custom code to switch off part of SSL checking).
Once you've done that (once) your code should run without any modifications.

Configuring Glassfish as a client of web services using mutual SSL

I'm trying to request data from a web service which requires a client certificate to be presented by a client. The server uses SSL for all communications, and uses a self-signed certificate. I gave Netbeans the service's WSDL file and it generated client code with wsimport.
I have no issues when my client code is written in a regular Java application; I set the trust store to the cacerts file containing the server's certificate, set the key store to be a file provided by the server admin in JKS format containing 2 keys - a client private key and the server's public key, build the request object, and send the request.
The problem comes when I move it to an enterprise Java environment. Requirements dictate that the code must be an Enterprise JavaBean inside an Enterprise Archive running on the Glassfish application server. It appears that Glassfish has its own security settings which override the JVM's settings. When the EJB method containing the web service call runs, the SSL negotiation fails: 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. I don't know how to set Glassfish's security settings up like my JVM's settings, can anyone explain Glassfish's security settings? The research I have done has only shown how to set up Glassfish as a web service server, not as a web service client.
I have a .cer certificate file for the server which I added it to my trust store by using Java's keytool to add it to the default cacerts file.
Would it be better to modify cacerts file with InstallCert to include the self-signed certificate, following the steps at http://blog.johnryding.com/post/1548502059/acquire-an-ssl-certificate-for-your-java-programs-in-win?
I have the trust store file, key store file, along with a .cer certificate file and a .p12 browser certificate, stored in $JAVA_HOME/jre/lib/security and $JAVA_HOME/lib/security.
I'm using Netbeans 6.9.1 and Glassfish 3.1 Final. The relevant piece of code is below, copied from my EJB. The exception occurs at the last line.
System.setProperty("javax.net.ssl.trustStore", "C:\\jssecacerts");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
System.setProperty("javax.net.ssl.keyStore", "C:\\userCertificate.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "password");
RequestObject request = new RequestObject;
request.setQuery("some data");
request.setUsername("user");
request.setPassword("pass");
Service service = new Service();
Endpoint port = service.getWebServicePort();
Result result = port.specificWebServiceMethod(request);
I faced the same exception that Jacques Pritchard described above:
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
I solved it importing the root certificate in both cacerts.jks and keystore.jks, using the following commands:
/usr/java/jdk1.6.0_25/bin/keytool -import -trustcacerts -file root_ca.cer -alias rootca -keystore cacerts.jks
/usr/java/jdk1.6.0_25/bin/keytool -import -trustcacerts -file root_ca.cer -alias rootca -keystore keystore.jks
It's important to say that the alias rootca is a name I defined myself to label the certificate. You can choose any name also.
Instead of using the global system properties, you should create a separate SSLContext for your client. Whether or not it runs within a Glassfish server doesn't really matter, then.
Here is a question that should be relevant (about client-certificates for WS): Choosing SSL client certificate in Java
I had this exact problem (with Glassfish 3.0.1).
Here are the exact steps we took to resolve this.
a. Use java keytool command to view the keystore to see what's in it. This is helpful later on to see if there are any changes. The command goes something like
keytool -list -keystore MyKeyStore.jks
b. Convert the pfx to a pem using openssl. Note that I used the correct password for the input pfx and the same password as my java keystore for the pem file output.
openssl pkcs12 -in MyPfxFile.pfx -out MyPemFile.pem
Convert the pem file to a p12 which can easily be imported into a java keystore. Note that I used the same password from my java keystore as I did on the input and output files.
openssl pkcs12 -export -in MyPemFile.pem -out MyP12File.p12
Now I finally import the p12 into my java keystore. Note that I used java 6, java 5 keytool doesn't have support for the -importkeystore argument.
keytool -importkeystore -deststorepass MyPassword -destkeystore PathToMyKeystore/keystore.jks -srckeystore MyP12File.p12 -srcstoretype PKCS12 -srcstorepass MyPassword
You can list the keystore contents here, something like this keytool -list -keystore keystore.jks just to ensure that your new key was imported correctly.
If you're lucky like I am you'll find that starting up your app server at this point will be of no use. You'll see errors like something about pkix path or something about HTTP 403 Forbidden.
The steps used above worked perfectly for Sun Application Server 9.1_1 but not for Oracle Glassfish 3.0.1. I'm thinking this has something to do with the version of JSSE used in ogs 3 compared to Sun App Server or jdk versions. Adding the jvm option below to your ogs 3 domain.xml file should resolve the issue if simply adding the client cert to the keystore didn't.
<jvm-options>-Djava.protocol.handler.pkgs=com.sun.net.ssl.internal.www.protocol</jvm-options>
I did notice that someone said to not use the jvm options statement above but it's part of the fix, don't use it and see if it works, I'll bet it won't. Maybe just changing the handlers is why it works?
Here's where I found the details: http://onjava.com/pub/a/onjava/2001/05/03/java_security.html?page=4
I also stumbled across a final issue (only for ogs 3), if you get fails every now and again I'd suggest finding the InstallCert app (its out there) and give it the following command line parameters:
I was getting these PKIX errors every third attempt at calling the web service.
Hopefully this helped someone else out. These kind of issues really make me want to rip my hair out :)
I finally got it.
Removed all the certs from my keytool.
Command Example : keytool -list -v -keystore keystore.jks -alias mydomain
I converted the cert response from server to bas64 DER and copied them into one file a .PEM, and I uploaded the .PEM into my keytool:
Command Example : keytool -importcert -keystore keystore.jks -alias mydomain -file my.pem
Then I loaded the keystore:
KeyStore myStore = KeyStore.getInstance("JKS");
InputStream keyInputx = new FileInputStream("C:\\myStore.jks");
myStore.load(keyInputx, "xxx".toCharArray());
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
keyInputx.close();
/*Enumeration enumeration = myStore.aliases();
while (enumeration.hasMoreElements()) {
String alias = (String) enumeration.nextElement();
System.out.println("alias name: " + alias);
Certificate certificate = myStore.getCertificate(alias);
System.out.println(certificate.toString());
}*/
keyManagerFactory.init(myStore, "xxx".toCharArray());
SSLContext context = SSLContext.getInstance("TLS");
context.init(keyManagerFactory.getKeyManagers(), null, new SecureRandom());
SSLSocketFactory sockFact = context.getSocketFactory();
Lots of references around so be happy to use.