Reputation: 863
I followed this tutorial for using a self signed certificate and that worked so far.
Then, I purchased a SSL certificate from my provider and tried to use that one. I get the error:
2019-04-19 17:45:36.385 ERROR 9245 --- [ restartedMain] org.apache.catalina.util.LifecycleBase : Failed to start component [Connector[HTTP/1.1-8443]]
org.apache.catalina.LifecycleException: Protocol handler start failed
at org.apache.catalina.connector.Connector.startInternal(Connector.java:1004) ~[tomcat-embed-core-9.0.14.jar:9.0.14]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[tomcat-embed-core-9.0.14.jar:9.0.14]
at org.apache.catalina.core.StandardService.addConnector(StandardService.java:226) [tomcat-embed-core-9.0.14.jar:9.0.14]
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.addPreviouslyRemovedConnectors(TomcatWebServer.java:259) [spring-boot-2.1.2.RELEASE.jar:2.1.2.RELEASE]
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.start(TomcatWebServer.java:197) [spring-boot-2.1.2.RELEASE.jar:2.1.2.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.startWebServer(ServletWebServerApplicationContext.java:311) [spring-boot-2.1.2.RELEASE.jar:2.1.2.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.finishRefresh(ServletWebServerApplicationContext.java:164) [spring-boot-2.1.2.RELEASE.jar:2.1.2.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549) [spring-context-5.1.4.RELEASE.jar:5.1.4.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:142) [spring-boot-2.1.2.RELEASE.jar:2.1.2.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775) [spring-boot-2.1.2.RELEASE.jar:2.1.2.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) [spring-boot-2.1.2.RELEASE.jar:2.1.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:316) [spring-boot-2.1.2.RELEASE.jar:2.1.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260) [spring-boot-2.1.2.RELEASE.jar:2.1.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248) [spring-boot-2.1.2.RELEASE.jar:2.1.2.RELEASE]
at de.tki.chinese.ChineseApplication.main(ChineseApplication.java:24) [classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_73]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_73]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_73]
at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_73]
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) [spring-boot-devtools-2.1.2.RELEASE.jar:2.1.2.RELEASE]
Caused by: java.lang.IllegalArgumentException: DerInputStream.getLength(): lengthTag=109, too big.
at org.apache.tomcat.util.net.AbstractJsseEndpoint.createSSLContext(AbstractJsseEndpoint.java:114) ~[tomcat-embed-core-9.0.14.jar:9.0.14]
at org.apache.tomcat.util.net.AbstractJsseEndpoint.initialiseSsl(AbstractJsseEndpoint.java:85) ~[tomcat-embed-core-9.0.14.jar:9.0.14]
at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:224) ~[tomcat-embed-core-9.0.14.jar:9.0.14]
at org.apache.tomcat.util.net.AbstractEndpoint.bindWithCleanup(AbstractEndpoint.java:1085) ~[tomcat-embed-core-9.0.14.jar:9.0.14]
at org.apache.tomcat.util.net.AbstractEndpoint.start(AbstractEndpoint.java:1171) ~[tomcat-embed-core-9.0.14.jar:9.0.14]
at org.apache.coyote.AbstractProtocol.start(AbstractProtocol.java:568) ~[tomcat-embed-core-9.0.14.jar:9.0.14]
at org.apache.catalina.connector.Connector.startInternal(Connector.java:1001) ~[tomcat-embed-core-9.0.14.jar:9.0.14]
... 19 common frames omitted
Caused by: java.io.IOException: DerInputStream.getLength(): lengthTag=109, too big.
at sun.security.util.DerInputStream.getLength(DerInputStream.java:561) ~[na:1.8.0_73]
at sun.security.util.DerValue.init(DerValue.java:365) ~[na:1.8.0_73]
at sun.security.util.DerValue.<init>(DerValue.java:320) ~[na:1.8.0_73]
at sun.security.pkcs12.PKCS12KeyStore.engineLoad(PKCS12KeyStore.java:1914) ~[na:1.8.0_73]
at java.security.KeyStore.load(KeyStore.java:1445) ~[na:1.8.0_73]
at org.apache.tomcat.util.net.SSLUtilBase.getStore(SSLUtilBase.java:178) ~[tomcat-embed-core-9.0.14.jar:9.0.14]
at org.apache.tomcat.util.net.SSLHostConfigCertificate.getCertificateKeystore(SSLHostConfigCertificate.java:204) ~[tomcat-embed-core-9.0.14.jar:9.0.14]
at org.apache.tomcat.util.net.jsse.JSSEUtil.getKeyManagers(JSSEUtil.java:203) ~[tomcat-embed-core-9.0.14.jar:9.0.14]
at org.apache.tomcat.util.net.AbstractJsseEndpoint.createSSLContext(AbstractJsseEndpoint.java:112) ~[tomcat-embed-core-9.0.14.jar:9.0.14]
... 25 common frames omitted
2019-04-19 17:45:36.405 INFO 9245 --- [ restartedMain] o.apache.catalina.core.StandardService : Stopping service [Tomcat]
2019-04-19 17:45:36.414 INFO 9245 --- [ restartedMain] ConditionEvaluationReportLoggingListener :
I created a keystore like this:
MacBook-Pro:keystore tobias$ keytool -import -alias tomcat -file hanzien_de.key -keystore keystore_hanzien.de.p12 -storepass xxxxx
Then I used that keystore in my application.properties file:
# ==============================================================
# = ssh
# ==============================================================
# Tell Spring Security (if used) to require requests over HTTPS
security.require-ssl=true
# The format used for the keystore
server.ssl.key-store-type=PKCS12
# The path to the keystore containing the certificate
server.ssl.key-store=classpath:keystore/keystore_hanzien.de.p12
#server.ssl.key-store=classpath:keystore/hanzien_de.pfx
# The password used to generate the certificate
server.ssl.key-store-password=xxxxx
# The alias mapped to the certificate
server.ssl.key-alias=tomcat
What am I doing wrong?
Upvotes: 2
Views: 12811
Reputation: 112
what about direct running from cmd
java -jar -Djavax.net.ssl.trustStoreType=JKS -Djavax.net.ssl.trustStorePassword=changeit -Djavax.net.ssl.trustStore=C:\Users\certificates\Cert_name -Dspring.profiles.active=local target\jar_or_war_name_with_dot_extension
Upvotes: 1
Reputation: 187
Faced with this error during Spring Boot Application with PCKS12 cert start. Simply rasing Java version from 8 to 11 fixed the error. Keep in mind that all the classes you use have to be in both versions of Java.
Upvotes: 0
Reputation: 38821
First, you appear to be using java 8 (8u73). Through 8 keytool
defaults to JKS format, not PKCS12. (9 up does default to PKCS12.) This is why your exception cause is about DerStuff; PKCS12 format is/uses DER but JKS not. Either specify -storetype pkcs12
on the keytool
command, or specify ..key-store-type=JKS
in your app config (and preferably change the name so it is not actively misleading and confusing to people).
Second, keytool -import
on a new keystore (or entry) imports only a certificate as a 'trustedcert' entry only usable to verify other parties. A TLS server (or SSL before it was obsoleted) like Tomcat, or in general any prover, must have a 'privatekey' entry containing a cert AND matching PRIVATEKEY AND usually CHAIN CERT(S). To be exact, the TLS standards require the server to send the/all chain cert(s) needed to verify the entity=server cert, optionally excluding the root or anchor; JSSE normally sends the cert(s) that are in the PrivateKeyEntry, so you must put the needed cert(s) there. For any public CA (like Verisign^WSymantec^WDigicert, GoDaddy, LetsEncrypt/Identrust) since about 1990, at least one chain cert is required, sometimes two and very rarely more. For a private CA this may vary depending on the CA. If the server does not send the required chain cert(s), some clients may still be able to verify some certs; in particular, browsers can often 'fill in' missing chain cert(s) from public CAs. This creates a situation where some connections to your server succeed while other connections to the same server fail, which tends to be very confusing and upsetting to users, and is not recommended.
If your .key
file actually contains only a cert, naming it .key
is misleading and confusing. If it contains a cert and then key in PEM, Java is able to read and separate the cert part and ignore the key; this allows keytool
to run but produces a resulting file that Tomcat cannot use to accept TLS/SSL connections. (Depending on the version and maybe config, it may throw a reasonably specific exception like 'not a key' or 'key not found', or it may simply reject all connection attempts with handshake_failure.) If it contains only a key, or a key then a cert, or not PEM, the keytool
command would fail, and yours apparently didn't.
keytool
is not able to import a privatekey from anything but a(nother) supported keystore, which doesn't help you much because if it's already in a keystore you don't need to import it. Your choices are:
if you have openssl
commandline, use it to convert the key + cert(s) to PKCS12. (openssl pkcs12 -export
will include chain cert(s) if you provide it/them explicitly, or explicitly specify -chain
and provide or default a truststore containing it/them.) There are dozens of existing Stack Qs and As, going back many years, covering this common and popular alternative.
use keytool
to generate the keypair (already in a Java-supported keystore format) and CSR and get a certificate issued for that CSR, and then use keytool -import
to either (1) import CA chain certs as trusted and then the server cert to the existing privatekey entry, which automatically fills in the chain or (2) import the whole CA chain directly to the existing privatekey entry. There are many existing Qs and As on this alternative also, as well as Sun/Oracle's own doc for Java, and tailored versions from every CA (or nearly so).
write, or find, and use a program that explicitly loads a privatekey and cert(s) from whatever format(s) you have to a 'privatekey' entry in a supported keystore. This is more work, and there are only a few Qs and As on this.
Upvotes: 2
Reputation: 1193
If you use maven, this is probably occurring because of the Maven filtering in your whole resources folder. Maven resource filtering (that let's you include variables in your resource files) can mess up your binaries - and certificates are especially sensitive to modification.
More about maven resource filtering: http://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html
Upvotes: 0