Tomcat 7 and invalid keystore format - java

I'm trying to connect to Tomcat through https on a remote server; I've found many answers, but no one has worked for me; I'm using Apache, Tomcat 7 on Ubuntu Server 14.04.
First, I created the certificate keystore writing:
keytool -genkey -alias tomcat -keyalg RSA
after I' ve edited "/etc/tomcat7/server.xml" to use ssl on port 8443:
<Connector port="8443" SSLEnabled="true"
protocol="org.apache.coyote.http11.Http11Protocol"
keystoreType="JKS"
maxThreads="150" scheme="https" secure="true"
keystoreFile="/usr/lib/jvm/java-7-openjdk-amd64/bin/keytool"
keystorePass="***********" keyAlias="tomcat"
clientAuth="false" sslProtocol="TLS"/>
where ********** is the password; restarting Tomcat through:
sudo service tomcat7 restart
I'm getting the following error in file "/var/log/tomcat7/catalina.out":
SEVERE: Failed to initialize connector [Connector[HTTP/1.1-8443]]
org.apache.catalina.LifecycleException: Failed to initialize component [Connector[HTTP/1.1-8443]]
at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:106)
at org.apache.catalina.core.StandardService.initInternal(StandardService.java:559)
at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:813)
at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
at org.apache.catalina.startup.Catalina.load(Catalina.java:638)
at org.apache.catalina.startup.Catalina.load(Catalina.java:663)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:280)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:454)
Caused by: org.apache.catalina.LifecycleException: Protocol handler initialization failed
at org.apache.catalina.connector.Connector.initInternal(Connector.java:980)
at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
... 12 more
Caused by: java.io.IOException: Invalid keystore format
at sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:650)
at sun.security.provider.JavaKeyStore$JKS.engineLoad(JavaKeyStore.java:55)
at java.security.KeyStore.load(KeyStore.java:1214)
at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getStore(JSSESocketFactory.java:392)
at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getKeystore(JSSESocketFactory.java:291)
at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getKeyManagers(JSSESocketFactory.java:549)
at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getKeyManagers(JSSESocketFactory.java:489)
at org.apache.tomcat.util.net.jsse.JSSESocketFactory.init(JSSESocketFactory.java:434)
at org.apache.tomcat.util.net.jsse.JSSESocketFactory.createSocket(JSSESocketFactory.java:181)
at org.apache.tomcat.util.net.JIoEndpoint.bind(JIoEndpoint.java:397)
at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:640)
at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:434)
at org.apache.coyote.http11.AbstractHttp11JsseProtocol.init(AbstractHttp11JsseProtocol.java:119)
at org.apache.catalina.connector.Connector.initInternal(Connector.java:978)
... 13 more
The keystore type is JKS, I've verified it through the command:
$JAVA_HOME/bin/keytool -list
which has returned:
Keystore type: JKS
Keystore provider: SUN
Your keystore contains 1 entry
tomcat, 17-Oct-2015, PrivateKeyEntry,
Certificate fingerprint (SHA1): 33:14:32:DD:DA:20:BF:CF:70:32:F5:0E:E9:F1:C1:5B:4E:C3:DB:AB
where $JAVA_HOME is "/usr/lib/jvm/java-7-openjdk-amd64";
So when I try to connect to "https://myServerIp:8443/" or to "https://myDomainName:8443/" I get "Unable to connect" error.

just to further support this answer for beginners like me. On Windows OS
First go to C:\Program Files\Java\jdk1.8,
Press Shift + right-click to open command pront: write this keytool.exe -genkey -alias tomcat -keyalg RSA -keystore /{user.name}/.keystore,
A sequence of question will then follow after that you will see a new .keytore generated at the specify path
Now you need to go to server.xml and modify this two keystoreFile="${user.home}/.keystore" keystorePass="changeit" with the appropriate one.

Now it works correctly, in short:
I specified the path of the .keystore file
I configured Tomcat to use this file
Thanks to #Titus I've understood where the problem was: when I run the command
keytool -genkey -alias tomcat -keyalg RSA
or the command
$JAVA_HOME/bin/keytool -genkey -keyalg RSA -alias tomcat
the program keytool create a file .keystore in a folder of the server; the directory /usr/lib/jvm/java-7-openjdk-amd64/jre/bin contains a file named keystore, but this file is not correct to setup tomcat or for some reason it doesn't work in my case.
To specify the path of the file .keystore we can run the command
keytool -genkey -alias tomcat -keyalg RSA -keystore /path/.keystore
and after that I've configured Tomcat editing the file /etc/tomcat7/server.xml with the file just created:
<Connector port="8443" SSLEnabled="true"
protocol="org.apache.coyote.http11.Http11Protocol"
keystoreType="JKS"
maxThreads="150" scheme="https" secure="true"
keystoreFile="/path/.keystore"
keystorePass="************" keyAlias="tomcat"
clientAuth="false" sslProtocol="TLS"/>

Related

Spring Boot / Jetty + SSL: Keystore not found (FileNotFoundException)

I am trying to enable SSL with embedded jetty in a Spring Boot Application.
Spring Boot Starter Version: 2.1.0.RELEASE
My configuration:
I created a keystore with the following command:
keytool -genkey -keyalg RSA -alias webapp -keystore keystore.jks -storepass password -keysize 2048
The resulting keystore.jks file was placed in src/main/resources/ssl.
The tutorials mostly say that referencing this keystore in the application.yaml should be enough to "make it work":
server:
port: 9292
servlet:
context-path: /
ssl:
key-store: classpath:keystore.jks
key-store-password: password
key-alias: webapp
key-store-type: JKS
Error:
When I try to start the application, it fails:
Caused by: org.springframework.boot.web.server.WebServerException: Could not find key store 'classpath:keystore.jks'
at org.springframework.boot.web.embedded.jetty.SslServerCustomizer.configureSslKeyStore(SslServerCustomizer.java:195) ~[spring-boot-2.1.0.RELEASE.jar:2.1.0.RELEASE]
at org.springframework.boot.web.embedded.jetty.SslServerCustomizer.configureSsl(SslServerCustomizer.java:164) ~[spring-boot-2.1.0.RELEASE.jar:2.1.0.RELEASE]
at org.springframework.boot.web.embedded.jetty.SslServerCustomizer.customize(SslServerCustomizer.java:73) ~[spring-boot-2.1.0.RELEASE.jar:2.1.0.RELEASE]
at org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory.customizeSsl(JettyServletWebServerFactory.java:195) ~[spring-boot-2.1.0.RELEASE.jar:2.1.0.RELEASE]
at org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory.getWebServer(JettyServletWebServerFactory.java:145) ~[spring-boot-2.1.0.RELEASE.jar:2.1.0.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:179) ~[spring-boot-2.1.0.RELEASE.jar:2.1.0.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:152) ~[spring-boot-2.1.0.RELEASE.jar:2.1.0.RELEASE]
... 13 common frames omitted
Caused by: java.io.FileNotFoundException: class path resource [keystore.jks] cannot be resolved to URL because it does not exist
at org.springframework.util.ResourceUtils.getURL(ResourceUtils.java:137) ~[spring-core-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.boot.web.embedded.jetty.SslServerCustomizer.configureSslKeyStore(SslServerCustomizer.java:190) ~[spring-boot-2.1.0.RELEASE.jar:2.1.0.RELEASE]
... 19 common frames omitted
When I look into the maven target directory though, the keystore.jks is placed under classes/ssl, so it should be in the classpath, right?
Can someone point out what I am missing?
Edit:
Strangely enough, moving the keystore.jks to src/main/resources seems to fix the problem. Why jetty able to find the keystore there, but not in the subdirectory src/main/resources/ssl?
Classpath by default is set tot src/main/resources. Meaning if you have subdirectories inside you need to specify the full path to your jks file:
key-store: classpath:ssl/keystore.jks

Enable HTTPS with self-signed certificate in Spring Boot 2.0

I'm following this tutorial to enable HTTPS in Spring Boot 2.0 using a self-signed certificate, just for testing purpose. In summary, that tutorial includes these steps:
1.Generate the keystore using keytool.
keytool -genkey -alias tomcat
-storetype PKCS12 -keyalg RSA -keysize 2048
-keystore keystore.p12 -validity 3650
2.Enable HTTPS in Spring Boot by adding some properties in the application.properties file.
server.port: 8443
server.ssl.key-store: keystore.p12
server.ssl.key-store-password: mypassword
server.ssl.keyStoreType: PKCS12
server.ssl.keyAlias: tomcat
3.Redirect HTTP to HTTPS (optional). I ignored this part.
But when I start my application, I got these error:
org.apache.catalina.LifecycleException: Failed to start component [Connector[HTTP/1.1-8443]]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:167) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
at org.apache.catalina.core.StandardService.addConnector(StandardService.java:225) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.addPreviouslyRemovedConnectors(TomcatWebServer.java:255) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.start(TomcatWebServer.java:197) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.startWebServer(ServletWebServerApplicationContext.java:300) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.finishRefresh(ServletWebServerApplicationContext.java:162) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:552) [spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:388) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:327) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1246) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1234) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
at epic.gwdg.restgraph.RestgraphApplication.main(RestgraphApplication.java:10) [classes/:na]
Caused by: org.apache.catalina.LifecycleException: Protocol handler start failed
at org.apache.catalina.connector.Connector.startInternal(Connector.java:1021) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
... 13 common frames omitted
Caused by: java.lang.IllegalArgumentException: Private key must be accompanied by certificate chain
at org.apache.tomcat.util.net.AbstractJsseEndpoint.createSSLContext(AbstractJsseEndpoint.java:116) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
at org.apache.tomcat.util.net.AbstractJsseEndpoint.initialiseSsl(AbstractJsseEndpoint.java:87) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:225) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
at org.apache.tomcat.util.net.AbstractEndpoint.start(AbstractEndpoint.java:1150) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
at org.apache.coyote.AbstractProtocol.start(AbstractProtocol.java:591) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
at org.apache.catalina.connector.Connector.startInternal(Connector.java:1018) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
... 14 common frames omitted
Caused by: java.lang.IllegalArgumentException: Private key must be accompanied by certificate chain
at java.base/java.security.KeyStore.setKeyEntry(KeyStore.java:1170) ~[na:na]
at org.apache.tomcat.util.net.jsse.JSSEUtil.getKeyManagers(JSSEUtil.java:257) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
at org.apache.tomcat.util.net.AbstractJsseEndpoint.createSSLContext(AbstractJsseEndpoint.java:114) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
... 19 common frames omitted
2018-03-16 16:42:30.917 INFO 970 --- [ main] o.apache.catalina.core.StandardService : Stopping service [Tomcat]
2018-03-16 16:42:30.931 INFO 970 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2018-03-16 16:42:30.933 ERROR 970 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
The Tomcat connector configured to listen on port 8443 failed to start. The port may already be in use or the connector may be misconfigured.
Action:
Verify the connector's configuration, identify and stop any process that's listening on port 8443, or configure this application to listen on another port.
2018-03-16 16:42:30.934 INFO 970 --- [ main] ConfigServletWebServerApplicationContext : Closing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext#58ce9668: startup date [Fri Mar 16 16:42:26 CET 2018]; root of context hierarchy
2018-03-16 16:42:30.936 INFO 970 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Unregistering JMX-exposed beans on shutdown
Process finished with exit code 1
Basically, the message is:
Private key must be accompanied by certificate chain.
This is a self-signed certificate, so it, of course, doesn't have the trusted chain. How can I fix it?
Here is my current application.properties file:
server.port=8443
server.ssl.enabled=true
server.ssl.key-store=classpath:keystore.p12
server.ssl.key-password=123456
server.ssl.key-store-type=PKCS12
server.ssl.key-alias=tomcat
Thank you so much for your help.
The problem is that in your generated keystore you dont have a key pair so there is no private key that's because your using the option -genkey you need to change it by the option -genkeypair :
-genkey generates a Secret Key whereas the -genkeypair generates a
key pair (a public key and a private key).
So I think this should work :
keytool -genkeypair -alias tomcat -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 3650
In your spring boot configuration change ":" by "=" and add the path to your keystore I suppose that your keystore.p12 is in your resources folder so :
server.ssl.key-store = classpath:keystore.p12
server.ssl.key-store-password = mypassword
server.ssl.key-store-type = PKCS12
server.ssl.key-alias = tomcat
I was getting this horrible Private key must be accompanied by certificate chain error as well on my Spring Boot application with an embedded Tomcat server. It was making me insane.
It turns out a simple typo was my problem:
#Override
public void customize(ConfigurableServletWebServerFactory server) {
Ssl ssl = new Ssl();
ssl.setEnabled(true);
ssl.setKeyStore(keystoreFile);
ssl.setKeyPassword(keystorePass); // << Should be `setKeyStorePassword` !!!!
ssl.setKeyStoreType(keystoreType);
ssl.setKeyAlias(keystoreAlias);
server.setSsl(ssl);
server.setPort(sslPort);
}
So the error message is not helpful at all for this case. I hope this helps someone else. Just be sure to verify that you're putting the right passwords (key vs keystore) in the right place. The same issue can happen in a properties based setup - it depends on what you are working with.
You made a small mistake in the application.properties file. Please change
server.ssl.key-password=your_password
to
server.ssl.key-store-password=your_password
It will work fine then. Hope it helps! Thank you!
1.use " -genkeypair"
keytool -genkeypair -alias tomcat -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 3650
change "server.ssl.key-password" to "server.ssl.key-store-password"
I had a similar problem, in my case i was missing the trustAnchors in the trust store.
One solution is to use the java built-in keytool, like explained in the other answers. But there is an even simplest approach using KeyStore Explorer GUI, so i'll explain the complete steps with both tools.
1. First of all, as described in the answer, we need to enable SSL in the application.properties file:
# <======= SSL Security ===========>
# Keystore config
server.ssl.key-store-type=PKCS12
server.ssl.key-store-password=change_it!
server.ssl.key-store=classpath:keystore.p12
server.ssl.key-alias=alias
server.ssl.enabled=true
# Trust Store Certificates
server.ssl.trust-store=classpath:trust_store.p12
server.ssl.trust-store-type=PKCS12
server.ssl.trust-store-password=07123e1f482356c415f684407
# <=====================>
The Keystore is the container of the Public - Private Key pair that is used by the server to communicate securely with the clients. The client of course must have the Public Key to be able to communicate with the server.
The Trust Store is simply a container for the certificates. (the Public Keys).
In our case it will contain only one certificate, the one used by the server.
2.1 Create the keystore with the java keytool:
keytool -genkeypair -alias alias -keyalg RSA -keysize 2048 -storetype PKCS12 -keystore keystore.p12 -validity 3650
2.2 Export the certificate so we can use it to create the Trust Store Keystore
keytool -export -keystore keystore.p12 -alias alias -file certificate.cer
2.3 This step will automatically create a new keystore with the imported trusted certificate. (The tool will ask you a password for the new keystrore and when it asks "Trust this certificate?" of course you should type "yes")
keytool -importcert -file certificate.cer -keystore trust_store.p12 -alias alias
Finally save both keystores inside the resources folder of your Spring Boot App (as shown in the alternative approach).
Alternative approach with KeyStore Explorer
2.1 Create the keystore with the KeyStore Explorer, as shown in the screenshots:
Then save the keystore inside the resources folder of your Spring Boot App:
2.2 Now we need to create the trust store, that can be given to the client that needs to communicate with our server. First of all extract the certificate chain created by the KeyStore Explorer and then create a new KeyStore importing the certificate inside it, as shown in the screenshots:
Then to create our trust store, click on "Create a new KeyStore" with the PKCS12 format as in the previous steps, the click the red icon "Import trusted certificate", choose the certificate saved in the preceding step, and finally save the keystore inside the resources folder like we did in the first keystore creation.
Now your server will be enabled to communicate with SSL security. Remember that your clients must be configured to load the trust store you've created .
Spring Boot 2.2.1.RELEASE
keytool -genkeypair -keystore myKeystore2.p12 -storetype PKCS12 -storepass 123456 -alias ks-localhost -keyalg RSA -keysize 2048 -validity 99999 -dname "CN=My SSL Certificate, OU=My Team, O=My Company, L=My City, ST=My State, C=SA" -ext san=dns:localhost,ip:127.0.0.1
application.yml
server:
tomcat:
accesslog:
enabled: true
ssl:
key-store-type: PKCS12
key-store: classpath:myKeystore.p12
key-alias: ks-localhost
enabled: true
protocol: TLS
key-store-password: 123456
I had the same problem. I made the changes from 2nd answer. But problem wasn't gone.
After all I've made, I just included my keystore.p12 certificate to pom.xml in profiles section
<profiles>
<!-- DEVELOPMENT PROFILE -->
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>application.properties</include>
<include>keystore.p12</include>
<include>data/**</include>
</includes>
</resource>
</resources>
</build>
</profile>
</profiles>

what is keyAlias="aaaa" in tomcat server.xml file

I have SSL certificate purchased and installed into tomcat. I created tomcat.keystore file which I include in server.xml file also put password but not able to understand keyAlias="aaa". If I put keyAlias="localhost" then I get exception given below. And if I remove keyAlias itself from the Connector tag then I get another exception which is given below next localhost exception.
java.io.IOException: Alias name localhost does not identify a key entry
at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getKeyManagers(JSSESocketFactory.java:588)
at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getKeyManagers(JSSESocketFactory.java:526)
at org.apache.tomcat.util.net.jsse.JSSESocketFactory.init(JSSESocketFactory.java:471)
at org.apache.tomcat.util.net.jsse.JSSESocketFactory.createSocket(JSSESocketFactory.java:218)
at org.apache.tomcat.util.net.JIoEndpoint.bind(JIoEndpoint.java:400)
at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:649)
Here is exception after removing keyAlias itself from the Connector tag.
Aug 08, 2015 2:39:18 PM org.apache.catalina.core.StandardService initInternal
SEVERE: Failed to initialize connector [Connector[HTTP/1.1-443]]
org.apache.catalina.LifecycleException: Failed to initialize component [Connector[HTTP/1.1-443]]
at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:106)
at org.apache.catalina.core.StandardService.initInternal(StandardService.java:559)
at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:821)
at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
at org.apache.catalina.startup.Catalina.load(Catalina.java:638)
at org.apache.catalina.startup.Catalina.load(Catalina.java:663)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:280)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:454)
Caused by: org.apache.catalina.LifecycleException: Protocol handler initialization failed
at org.apache.catalina.connector.Connector.initInternal(Connector.java:980)
at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
... 12 more
Caused by: java.net.BindException: Address already in use <null>:443
at org.apache.tomcat.util.net.JIoEndpoint.bind(JIoEndpoint.java:413)
at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:649)
at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:434)
at org.apache.coyote.http11.AbstractHttp11JsseProtocol.init(AbstractHttp11JsseProtocol.java:119)
at org.apache.catalina.connector.Connector.initInternal(Connector.java:978)
... 13 more
Caused by: java.net.BindException: Address already in use
at java.net.PlainSocketImpl.socketBind(Native Method)
at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:376)
at java.net.ServerSocket.bind(ServerSocket.java:376)
at java.net.ServerSocket.<init>(ServerSocket.java:237)
at java.net.ServerSocket.<init>(ServerSocket.java:181)
at javax.net.ssl.SSLServerSocket.<init>(SSLServerSocket.java:136)
at sun.security.ssl.SSLServerSocketImpl.<init>(SSLServerSocketImpl.java:107)
at sun.security.ssl.SSLServerSocketFactoryImpl.createServerSocket(SSLServerSocketFactoryImpl.java:84)
at org.apache.tomcat.util.net.jsse.JSSESocketFactory.createSocket(JSSESocketFactory.java:219)
at org.apache.tomcat.util.net.JIoEndpoint.bind(JIoEndpoint.java:400)
... 17 more
Following is the content of server.xml file.
<Connector port="443" SSLEnabled="true" protocol="org.apache.coyote.http11.Http11Protocol"
maxThreads="150" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystoreFile="tomcat.keystore"
keystorePass="test" keyAlias="aaa"/>
What is that keyAlias ? Why am I getting exception after removing it which is Binding exception ?
KEYALIAS:
https://www.digicert.com/ssl-certificate-installation-tomcat.htm`
When you import your certificate into the keystore, you would typically give an "alias":
keytool -import -trustcacerts -alias server -file your_site_name.p7b -keystore your_site_name.jks
In your server.xml, you must then declare the same "alias":
<Connector port="443" maxHttpHeaderSize="8192" maxThreads="150"
minSpareThreads="25" maxSpareThreads="75" enableLookups="false"
disableUploadTimeout="true" acceptCount="100" scheme="https"
secure="true" SSLEnabled="true" clientAuth="false" sslProtocol="TLS"
keyAlias="server" keystoreFile="/home/user_name/your_site_name.jks"
keystorePass="your_keystore_password" />
Here are some other links that might help:
https://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html
https://www.mulesoft.com/tcat/tomcat-ssl
https://wolfpaulus.com/jounal/mac/tomcat-ssl/
SECOND ISSUE, "CAN'T BIND":
As far as "address in use", I would simply try rebooting the server and see if Tomcat starts correctly.
If you encounter the error again,
Look in your Tomcat settings to see which port you're trying to use (e.g. 443)
Check your system to see who else is using the port (lsof, nmap, etc):
http://www.howtogeek.com/howto/28609/how-can-i-tell-what-is-listening-on-a-tcpip-port-in-windows/
https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/3/html/Security_Guide/s1-server-ports.html
These errors are not related.
keyAlias is documented in the Tomcat documentation, and that is where you should look for its meaning.
The error you have made is to not import the signed certificate with the same alias you used when generating the keypair. They must be the same so that they keytool will associate the keypair with the certificate and create a key entry instead of a certificate entry.
The BindException means that some other process, probably a prior invocation of Tomcat that hasn't exited yet, is using the port. Or possibly you have configured two Connectors to use the same port. It only shows up as an error when you configure the SSL connector correctly.

OpenSSL certificate is giving 'Invalid keystore format' in tomcat 8

I am using tomcat 8 and need to make it SSL, So I use openSSL to generate self signed certificate and configured the same in tomcat's server.xml file. But I am getting the below exception
INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["http-nio-7443"]
16-Apr-2015 09:50:56.647 SEVERE [main] org.apache.coyote.AbstractProtocol.init Failed to initialize end point associated with ProtocolHandler ["http-nio-7443"]
java.io.IOException: Invalid keystore format
at sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:650)
at sun.security.provider.JavaKeyStore$JKS.engineLoad(JavaKeyStore.java:55)
at java.security.KeyStore.load(KeyStore.java:1433)
at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getStore(JSSESocketFactory.java:424)
at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getKeystore(JSSESocketFactory.java:323)
at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getKeyManagers(JSSESocketFactory.java:581)
at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getKeyManagers(JSSESocketFactory.java:521)
at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:363)
at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:730)
at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:457)
at org.apache.coyote.http11.AbstractHttp11JsseProtocol.init(AbstractHttp11JsseProtocol.java:120)
at org.apache.catalina.connector.Connector.initInternal(Connector.java:960)
at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
at org.apache.catalina.core.StandardService.initInternal(StandardService.java:567)
at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:851)
at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
at org.apache.catalina.startup.Catalina.load(Catalina.java:576)
at org.apache.catalina.startup.Catalina.load(Catalina.java:599)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
Write failed: Broken pipegMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43
That trace points to invalid format on your keystore.
Check this:
keytool -list -v -keystore keystore.jks
Are certificates listed in your keystore?
If you generated it with OpenSSL maybe you are generating a pkcs12 and if you import this and use a Connector on Tomcat without specifying the format, according to the default keyStoreType value, it's setted as "JKS".
https://tomcat.apache.org/tomcat-8.0-doc/config/http.html
keystoreType The type of keystore file to be used for the server
certificate. If not specified, the default value is "JKS".
Using keytool:
I suggest: try to generate the keystore with keytool (for me it's easier):
https://www.sslshopper.com/article-most-common-java-keytool-keystore-commands.html?jn45301e6e=2
Generate a keystore and self-signed certificate:
keytool -genkey -keyalg RSA -alias selfsigned -keystore keystore.jks -storepass password -validity 360 -keysize 2048
Using PKCS12
Or if you pefer, you can also use a PKCS12 (if it's your case) with Tomcat:
Edit the JAVA_HOME/jre/lib/security/java.security file and change the default keystore type:
# Default keystore type.
keystore.type=pkcs12
Then configure your Connector with something similar to:
<!-- Define a SSL Coyote HTTP/1.1 Connector on port 8443 -->
<Connector port="8443"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" disableUploadTimeout="true"
acceptCount="100" debug="0" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystoreType="PKCS12"
keystoreFile="yourKey.p12"
keystorePass="endeca"
truststoreType="PKCS12"
truststoreFile="yourKey.p12"
truststorePass="pass" />
In my case, openssl.exe which Tomcat recognized did not match with Tomcat Native Library(tcnative-1.dll).
I downloaded them from https://archive.apache.org/dist/tomcat/tomcat-connectors/native then ssl worked.

java.security.SignatureException: Signature does not match

I created a java keystore with name cloudsslkeystore.jks
keytool -genkeypair -validity 730 -alias cloudsslkey -keystore cloudsslkeystore.jks -dname "cn=localhost" -keypass password -storepass password
I exported it as certificate with name cloudcertificate.cer
keytool -export -rfc -keystore cloudsslkeystore.jks -alias cloudsslkey -file cloudcertificate.cer
Enter keystore password:password
Certificate stored in file <cloudcertificate.cer>
I added the certificate cloudcertificate.cer to my local java security folder
C:\Program Files\Java\jre7\lib\security>keytool -keystore cacerts -importcert -noprompt -trustcacerts -alias cloudsslkey -file cloudcertificate.cer
Enter keystore password:changeit
Certificate was added to keystore
Now I used the same java keystore cloudsslkeystore.jks in tomcat server of a different machine by modifying server.xml
<Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS" keystoreFile="c:\keytool\cloudsslkeystore.jks" keystorePass="password" />
When I try to hit a webservice thru a java client, I get this exception.
Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: Problem writing SAAJ model to stream: sun.security.validator.ValidatorException: PKIX
path validation failed: java.security.cert.CertPathValidatorException: signature check failed
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:159)
at com.sun.proxy.$Proxy39.getAllRecommendations(Unknown Source)
at client.WSClient.main(WSClient.java:73)
Caused by: com.ctc.wstx.exc.WstxIOException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValida
torException: signature check failed
at com.ctc.wstx.sw.BaseStreamWriter.writeCharacters(BaseStreamWriter.java:458)
at org.apache.cxf.staxutils.StaxUtils.copy(StaxUtils.java:749)
at org.apache.cxf.staxutils.StaxUtils.copy(StaxUtils.java:696)
at org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor$SAAJOutEndingInterceptor.handleMessage(SAAJOutInterceptor.java:214)
at org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor$SAAJOutEndingInterceptor.handleMessage(SAAJOutInterceptor.java:174)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:514)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:423)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:326)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:279)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:137)
... 2 more
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathVal
idatorException: signature check failed
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1884)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:276)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:270)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1341)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:153)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:804)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1016)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1323)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:563)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1091)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:250)
at org.apache.cxf.transport.http.URLConnectionHTTPConduit$URLConnectionWrappedOutputStream.setupWrappedStream(URLConnectionHTTPConduit.java:17
4)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleHeadersTrustCaching(HTTPConduit.java:1302)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.onFirstWrite(HTTPConduit.java:1258)
at org.apache.cxf.transport.http.URLConnectionHTTPConduit$URLConnectionWrappedOutputStream.onFirstWrite(URLConnectionHTTPConduit.java:201)
at org.apache.cxf.io.AbstractWrappedOutputStream.write(AbstractWrappedOutputStream.java:47)
at org.apache.cxf.io.AbstractThresholdOutputStream.unBuffer(AbstractThresholdOutputStream.java:89)
at org.apache.cxf.io.AbstractThresholdOutputStream.write(AbstractThresholdOutputStream.java:63)
at org.apache.cxf.io.CacheAndWriteOutputStream.write(CacheAndWriteOutputStream.java:80)
at org.apache.cxf.io.AbstractWrappedOutputStream.write(AbstractWrappedOutputStream.java:51)
at com.ctc.wstx.io.UTF8Writer.write(UTF8Writer.java:143)
at com.ctc.wstx.sw.BufferingXmlWriter.writeRaw(BufferingXmlWriter.java:285)
at com.ctc.wstx.sw.BufferingXmlWriter.writeCharacters(BufferingXmlWriter.java:603)
at com.ctc.wstx.sw.BaseStreamWriter.writeCharacters(BaseStreamWriter.java:456)
... 13 more
Caused by: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: signature check fail
ed
at sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:350)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:260)
at sun.security.validator.Validator.validate(Validator.java:260)
at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:326)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:231)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:126)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1323)
... 37 more
Caused by: java.security.cert.CertPathValidatorException: signature check failed
at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:159)
at sun.security.provider.certpath.PKIXCertPathValidator.doValidate(PKIXCertPathValidator.java:351)
at sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:191)
at java.security.cert.CertPathValidator.validate(CertPathValidator.java:279)
at sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:345)
... 43 more
Caused by: java.security.SignatureException: Signature does not match.
at sun.security.x509.X509CertImpl.verify(X509CertImpl.java:451)
at sun.security.provider.certpath.BasicChecker.verifySignature(BasicChecker.java:160)
at sun.security.provider.certpath.BasicChecker.check(BasicChecker.java:139)
at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:133)
... 47 more
I finally found the problem:
The SignatureException does not indicate that the issuer is unknown to the client. In that case a CertPathBuilderException would be thrown.
The SignatureException was actually caused by not having the self-signed certificate imported as trusted certificate which must be done by the additional parameter -trustcacerts.
To answer the question why someone should want to trust a self signed certificate: The server is used for test purposes for automated client tests connecting to the server over HTTPS.
The Signature does not match error is the symptom that the server identity is unknown to the client, ie the client truststore does not have the server certificate.
Create the server certificate and add it to a keystore:
keytool -genkey -noprompt -alias "$alias" -dname "CN=$dname_cn, OU=$dname_ou, O=$dname_o, L=$dname_l, S=$dname_s, C=$dname_c" -keystore "$keystore" -storepass "$storepass" -keypass "$keypass"
and export it for the client into a truststore:
keytool -export -alias "$alias" -storepass "$storepass" -file "$alias".cer -keystore "$keystore"
If you want 2-way SSL then you have to repeat this twice, inverting, they both must know each other.
Now the tricky part is to build an SSLContext correctly and configure your client and server with it.
In Grizzly I do:
SSLContextConfigurator sslContextConfigurator = new SSLContextConfigurator();
// set up security context
sslContextConfigurator.setKeyStoreFile(configuration.getKeystore()); // contains the server keypair
sslContextConfigurator.setKeyStorePass(configuration.getKeystorePassword());
sslContextConfigurator.setKeyStoreType(configuration.getKeystoreType());
sslContextConfigurator.setKeyPass(configuration.getKeystoreKeypass());
sslContextConfigurator.setTrustStoreFile(configuration.getTruststore()); // contains the list of trusted certificates
sslContextConfigurator.setTrustStorePass(configuration.getTruststorePassword());
sslContextConfigurator.setTrustStoreType(configuration.getTruststoreType());
if (!sslContextConfigurator.validateConfiguration(true))
throw new Exception("Invalid SSL configuration");
For advanced debugging do not forget System.setProperty("javax.net.debug", "all");
-keypass password
Get rid of this parameter. The mechanism that supports javax.net.ssl.keyStore and javax.net.ssl.keyStorePassword doesn't support key passwords, only keystore passwords.

Categories

Resources