在spring启动应用程序中使用ssl证书

问题描述 投票:0回答:2

我遵循this教程使用自签名证书,到目前为止工作。

然后,我从我的提供商处购买了SSL证书并尝试使用该证书。我收到错误:

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 : 

我创建了一个这样的密钥库:

MacBook-Pro:keystore tobias$ keytool -import -alias tomcat -file hanzien_de.key -keystore keystore_hanzien.de.p12 -storepass xxxxx

然后我在application.properties文件中使用了该密钥库:

# ==============================================================
# = 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

我究竟做错了什么?

spring-boot ssl ssl-certificate
2个回答
0
投票

首先,您似乎使用的是java 8(8u73)。通过8个keytool默认为JKS格式,而不是PKCS12。 (9 up默认为PKCS12。)这就是你的异常原因是关于DerStuff的原因; PKCS12格式是/使用DER而不是JKS。在-storetype pkcs12命令中指定keytool,或在应用程序配置中指定..key-store-type=JKS(最好更改名称,以免它对人们产生误导和混淆)。

其次,新密钥库(或条目)上的keytool -import仅将证书导入为“trustedcert”条目,仅可用于验证其他方。 TLS服务器(或者在它被淘汰之前的SSL),如Tomcat,或者通常是任何证明者,必须有一个'privatekey'条目,其中包含一个证书并且匹配PRIVATEKEY,通常是CHAIN CERT(S)。确切地说,TLS标准要求服务器发送验证entity = server cert所需的/所有链证书,可选地排除根或锚; JSSE通常发送PrivateKeyEntry中的证书,因此您必须将所需的证书放在那里。对于任何公共CA(如Verisign ^ WSymantec ^ WDigicert,GoDaddy,LetsEncrypt / Identrust)自1990年左右以来,至少需要一个链证书,有时两个,很少更多。对于私有CA,这可能因CA而异。如果服务器未发送所需的链证书,则某些客户端仍可能能够验证某些证书;特别是,浏览器通常可以从公共CA“填写”缺失的链证书。这会导致与服务器的某些连接成功而与同一服务器的其他连接失败,这往往会让用户感到非常困惑和不安,并且不建议这样做。

如果你的.key文件实际上只包含一个证书,那么命名为.key会产生误导和混淆。如果它包含一个证书然后键入PEM,Java就能够读取并分离证书部分并忽略该密钥;这允许keytool运行,但会生成Tomcat无法用于接受TLS / SSL连接的结果文件。 (根据版本和可能的配置,它可能抛出一个合理的特定异常,例如'not a key'或'key not found',或者它可能只是拒绝所有与handshake_failure的连接尝试。)如果它只包含一个键,或者一个密钥,然后一个证书,或不是PEM,keytool命令会失败,你的显然没有。

keytool无法从除了(另一个)支持的密钥库之外的任何东西导入私钥,这对您没有多大帮助,因为如果它已经在密钥库中,您不需要导入它。你的选择是:

  • 如果您有openssl命令行,请使用它将密钥+证书转换为PKCS12。 (openssl pkcs12 -export将包括链证书,如果您明确提供它们,或明确指定-chain并提供或默认包含它/它们的信任库。)有许多现有的Stack Qs和As,可以追溯到很多年,涵盖了这个常见和流行的替代品。
  • 使用keytool生成密钥对(已经采用Java支持的密钥库格式)和CSR并获得为该CSR颁发的证书,然后使用keytool -import(1)将CA链证书导入为受信任,然后将服务器证书导入现有privatekey条目,自动填充链或(2)将整个CA链直接导入现有的私钥条目。此替代方案中还有许多现有的Q和As,以及Sun / Oracle自己的Java文档,以及来自每个CA(或几乎如此)的定制版本。
  • 编写,查找和使用一个程序,该程序从您拥有的任何格式显式加载私钥和证书到受支持的密钥库中的“私钥”条目。这是更多的工作,并且只有少数Q和As。

0
投票

如果你使用maven,这可能是因为整个资源文件夹中的Maven过滤。 Maven资源过滤(让您在资源文件中包含变量)可能会弄乱您的二进制文件 - 并且证书对修改特别敏感。

有关maven资源过滤的更多信息:http://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html

© www.soinside.com 2019 - 2024. All rights reserved.