My web application and Web Services are running in the same tomcat container. If I am not using HTTPS, everything is working fine.
When I am running the web application and web services both on HTTPS, I am getting SSLHandshakeException when web application is trying to call webservices.
CASE 1
I have created a local self-signed certificate file using below command
%JAVA_HOME%\bin\keytool -genkeypair -alias test1 -keyalg RSA -keystore c:/apps/test1.crt
A certificate file named test1.crt has been created in folder C:\apps.
Now, I want to import this certificate in the Java keystore, with the below command
%JAVA_HOME%\bin\keytool -import -alias test1 -file c:/apps/test1.crt-keystore %JAVA_HOME%/jre/lib/security/cacerts -storepass changeit
I am getting below error -
Key tool error: java.lang.Exception: The entry is not an X.509 certificate
When I am using this certificate file in Tomcat, with below setting
<Connector port="8443"
maxHttpHeaderSize="8192"
maxThreads="150"
minSpareThreads="25"
maxSpareThreads="75"
enableLookups="false"
disableUploadTimeout="true"
acceptCount="100"
scheme="https"
secure="true"
clientAuth="false"
sslProtocol="TLS"
SSLEnabled="true"
URIEncoding="UTF-8"
keystorePass="changeit"
keystoreFile="C:/apps/test2.crt" />
I am not getting any error at server startup. When I call webservices from the application, I am getting SSLHandshakeException
CASE 2
I have added a local self signed certificate in the Java keystore, with below command
%JAVA_HOME%/bin/keytool -genkeypair -alias test2 -keyalg RSA -validity 1000 -keysize 2048 -keystore %JAVA_HOME%/jre/lib/security/cacerts
A certificate has been added, which I have verfied with below command
JAVA_HOME%\bin\keytool -list -keystore %JAVA_HOME%/jre/lib/security/cacerts -storepass changeit
Now, I have exported a certificate file from the Java keystore, with below command
%JAVA_HOME%/bin/keytool -export -alias test2 -keystore %JAVA_HOME%/jre/lib/security/cacerts -rfc -file C:/apps/test2.crt
A certificate file named test2.crt has been created in folder C:\apps.
When I am using this certificate file in Tomcat, with below setting
<Connector port="8443"
maxHttpHeaderSize="8192"
maxThreads="150"
minSpareThreads="25"
maxSpareThreads="75"
enableLookups="false"
disableUploadTimeout="true"
acceptCount="100"
scheme="https"
secure="true"
clientAuth="false"
sslProtocol="TLS"
SSLEnabled="true"
URIEncoding="UTF-8"
keystorePass="changeit"
keystoreFile="C:/apps/test2.crt" />
I am getting the below error
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:491)
Caused by: java.lang.IllegalArgumentException: Invalid keystore format
at org.apache.tomcat.util.net.AbstractJsseEndpoint.createSSLContext(AbstractJsseEndpoint.java:114)
at org.apache.tomcat.util.net.AbstractJsseEndpoint.initialiseSsl(AbstractJsseEndpoint.java:85)
at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:224)
at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:1044)
at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:540)
at org.apache.coyote.http11.AbstractHttp11Protocol.init(AbstractHttp11Protocol.java:74)
at org.apache.catalina.connector.Connector.initInternal(Connector.java:932)
... 13 more
Caused by: java.io.IOException: Invalid keystore format
at sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:663)
at sun.security.provider.JavaKeyStore$JKS.engineLoad(JavaKeyStore.java:56)
at sun.security.provider.KeyStoreDelegator.engineLoad(KeyStoreDelegator.java:224)
at sun.security.provider.JavaKeyStore$DualFormatJKS.engineLoad(JavaKeyStore.java:70)
at java.security.KeyStore.load(KeyStore.java:1445)
at org.apache.tomcat.util.net.SSLUtilBase.getStore(SSLUtilBase.java:160)
Although server started and I am able to use my application. But when I am trying to call web services, I am getting
Here is the log of SSLHandshakeException
nested 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
Error: (org.apache.axis.AxisFault) --> [; nested 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]
AxisFault
faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
faultSubcode:
faultString: 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
faultActor:
faultNode:
faultDetail:
{http://xml.apache.org/axis/}stackTrace: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 think for Tomcat the keystoreFile is "%JAVA_HOME%/jre/lib/security/cacerts" and rather you don't have to indicate any keystore becouse you added a keypair to the jre common keystore but it's exactly incorrect to use "C:/apps/test2.crt".
Also try to add the server certificate to the truststore file:
JAVA_HOME%\bin\keytool -import -v -trustcacerts -alias test2 -file C:/apps/test2.crt -keystore %JAVA_HOME%/jre/lib/security/cacerts -keypass changeit -storepass changeit
Related
This question already has answers here:
"PKIX path building failed" and "unable to find valid certification path to requested target"
(53 answers)
Unable to find valid certification path to requested target - error even after cert imported
(17 answers)
Java: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
(29 answers)
Resolving javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed Error?
(33 answers)
Closed 7 months ago.
Tomcat configured for both 8080 and 8443:
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<Connector port="8443" protocol="HTTP/1.1"
connectionTimeout="20000"
scheme="https"
secure="true"
SSLEnabled="true">
<SSLHostConfig>
<Certificate certificateKeyAlias="tomcat"
certificateKeystoreFile="certificates/tomcat.jks"
certificateKeystorePassword="changeit"
truststoreFile="certificates/tomcat.jks"
truststorePassword="changeit" />
</SSLHostConfig>
</Connector>
This code works:
HttpRequest request = HttpRequest.newBuilder()
.uri( new URI( "http://localhost:8080/application/" ) )
.headers( "Content-Type", "application/xml" )
.headers( "Accept", "application/xml" )
.POST( HttpRequest.BodyPublishers.ofString( PAYLOAD ) )
.build();
HttpResponse< String > response = client.send( request, HttpResponse.BodyHandlers.ofString() );
while the HTTPS code fails with IOException: PKIX path building failed: SunCertPathBuilderException: unable to find valid certification path to requested target:
HttpRequest request = HttpRequest.newBuilder()
.uri( new URI( "https://localhost:8443/application/" ) )
.headers( "Content-Type", "application/xml" )
.headers( "Accept", "application/xml" )
.POST( HttpRequest.BodyPublishers.ofString( PAYLOAD ) )
.build();
HttpResponse< String > response = client.send( request, HttpResponse.BodyHandlers.ofString() );
...despite running JVM with:
-Djavax.net.ssl.keyPassword=changeit
-Djavax.net.ssl.keyStore=/opt/tomcat/certificates/tomcat.jks
-Djavax.net.ssl.keyStorePassword=changeit
-Djavax.net.ssl.trustStore=/opt/tomcat/certificates/trust.jks
-Djavax.net.ssl.trustStorePassword=changeit
Here's how I built the certificate artifacts:
$ keytool -genkeypair -alias tomcat -keyalg RSA -keypass changeit -storepass changeit -validity 365 -keystore tomcat.jks -dname "cn=windofkeltia.com"
$ keytool -export -alias tomcat -file tomcat.crt -keystore tomcat.jks-storepass changeit
$ openssl genrsa -out trust.key 2048
$ openssl req -new -x509 -days 365 -key trust.key -out trust.crt -subj "/CN=windofkeltia.com/"
$ keytool -importcert -alias tomcat -file trust.crt -keystore trust.jks -storePass changeit
# ll
-rw-r--r-- 1 tomcat tomcat 863 Jul 28 11:32 tomcat.crt
-rw-r--r-- 1 tomcat tomcat 2697 Jul 28 11:31 tomcat.jks
-rw-r--r-- 1 tomcat tomcat 1314 Jul 28 15:26 trust.crt
-rw-r--r-- 1 tomcat tomcat 1287 Jul 28 15:26 trust.jks
-rw------- 1 tomcat tomcat 1679 Jul 28 15:26 trust.key
I have created a certificate with OpenSSL
openssl genrsa -des3 -out server.key 2048
openssl rsa -in server.key -out server.key
openssl req -new -key server.key -out server.csr
keytool -import -trustcacerts -alias server.key -file server.crt -keystore
and placed keystore.jks into ${catalina.home}/lib/
server.xml
<Connector port="9002"
maxHttpHeaderSize="8192"
maxPostSize="4194304"
maxThreads="150"
protocol="org.apache.coyote.http11.Http11Protocol"
executor="hybrisExecutor"
enableLookups="false"
acceptCount="100"
connectionTimeout="20000"
disableUploadTimeout="true"
URIEncoding="UTF-8"
SSLEnabled="true"
scheme="https"
secure="true"
clientAuth="false"
sslProtocol = "TLS"
sslEnabledProtocols="TLSv1,TLSv1.1,TLSv1.2"
keystoreFile="${catalina.home}/lib/keystore.jks"
keystorePass="123456"
On Chrome it gives following error:
This site can’t provide a secure connection
13.236.191.242 uses an unsupported protocol.
ERR_SSL_VERSION_OR_CIPHER_MISMATCH
Unsupported protocol
The client and server don't support a common SSL protocol version or cipher suite.
curl -Iv https://11.231.191.212:9001/
Trying 11.231.191.212...
TCP_NODELAY set
Connected to 11.231.191.212 (11.231.191.212) port 9001 (#0)
schannel: SSL/TLS connection with 11.231.191.212 port 9001 (step 1/3)
schannel: checking server certificate revocation
schannel: using IP address, SNI is not supported by OS.
schannel: sending initial handshake data: sending 156 bytes...
schannel: sent initial handshake data: sent 156 bytes
schannel: SSL/TLS connection with 11.231.191.212 port 9001 (step 2/3)
schannel: failed to receive handshake, need more data
The problem was that I was creating a Self-signed certificate with OpenSSL. But when I generated the certificate from java Keystore then it works perfectly.
keytool.exe -genkey -alias tomcat -keyalg RSA -keystore c:\tomcatkeys
The reason was OpenSSL and keystore produce certificate in different file formats. You see the difference from the link below.
https://security.stackexchange.com/questions/98282/difference-between-openssl-and-keytool
I am getting following Exception when HTTPS Request is sent from Grails Web Application deployed in Tomcat Server(8):
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
Here is When I make HTTPS Call(On which Point I get this Exception):
String URL = "https://**.**.**.**:8440/*****";
PostMethod postMethod = new PostMethod(URL);
client.executeMethod(postMethod);
I have created the keystore file using keytool command:
keytool -genkey -alias tomcat -keyalg RSA
and changed the server.xml file too of Tomcat but still getting this exception. Here is my Server.XML File:
<Connector SSLEnabled="true" acceptCount="100" clientAuth="false" disableUploadTimeout="true" enableLookups="false" maxThreads="25"
port="443" keystoreFile="/keystore/keystore.jks" keystorePass="password" protocol="org.apache.coyote.http11.Http11NioProtocol" scheme="https" secure="true" sslProtocol="TLS" />
<!-- Define an AJP 1.3 Connector on port 8009 -->
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
I have gone through the following possible fixes for this but no luck:
http://java.dzone.com/articles/setting-ssl-tomcat-5-minutes
https://tomcat.apache.org/tomcat-3.3-doc/tomcat-ssl-howto.html
http://tomcat.apache.org/tomcat-4.1-doc/ssl-howto.html
P.S. I simply want tomcat to allow my application to hit HTTPS request for the URL:
String URL = "https://**.**.**.**:8440/*****";
I am rolling my head on this but unfortunately not getting through. Please guide me that what could be the fix for this ? Or I am doing anything wrong ?
Thanks for Your Time :)
I have an application running in Eclipse, works fine, connect and get a response from webservice that needs a certificate.
But when I deploy and run in Tomcat, I got a error of valid certification:
java.lang.Exception
Message
; nested 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
In my tomcat:
<Connector SSLEnabled="true" acceptCount="100" clientAuth="false"
disableUploadTimeout="true" enableLookups="false" maxThreads="25"
port="8443" keystoreFile="webapps/.keystore" keystorePass="123456"
protocol="org.apache.coyote.http11.Http11NioProtocol" scheme="https"
secure="true" sslProtocol="TLS" />
and in my application, I have another keystore to webservice:
System.setProperty("javax.net.ssl.keyStore", SIC.jks);
System.setProperty("javax.net.ssl.keyStore", keyStore);
System.setProperty("javax.net.ssl.keyStorePassword", keyStorePassword);
System.setProperty("javax.net.ssl.trustStore", trustStore);
System.setProperty("javax.net.ssl.trustStorePassword", trustStorePassword);
I tried import certificate to cacerts from keytool and nothing...
I don't have any one idea and my time is over in my job...What can I do to resolve that?
I tried everything I guess...works at Eclipse but on deploy tomcat, I got that error above.
Two suggestions
1. Specify the entire path for the keystoreFile. Eg /opt/webapps/.keystore
2. Do not use special characters "#" in the password.
I have created a certificate in my system using this command:
keytool -export -file test.cert -keystore test -storepass 123456 -alias sriram
Ans: Certificate stored in file <test.cert>.
I have imported this certificate in cacerts of new system using the command :
keytool -importcert -trustcacerts -file "path-to-public-cert" -keystore JAVA_HOME/jre/lib/security/cacerts".
The output is something like this:Trust this certificate? [no]: yes Certificate was added to keystore.
But still I am getting the link error when I run my jar file in new system...Where I went wrong??
Try to read the Apache Tomcat SSL Configuration How-To.
In Edit the Tomcat Configuration File paragraph it explain that you can had the keystoreFile attribute to the connector configuration.
<Connector
port="8443" maxThreads="200"
scheme="https" secure="true" SSLEnabled="true"
keystoreFile="${user.home}/.keystore" keystorePass="changeit"
clientAuth="false" sslProtocol="TLS"/>