Я следую этот учебник, чтобы включить HTTPS в Spring Boot 2.0 с использованием самозаверяющего сертификата, просто для целей тестирования. Таким образом, этот учебник включает в себя следующие шаги:
1. Сгенерируйте хранилище ключей с помощью keytool.
keytool -genkey -alias tomcat
-storetype PKCS12 -keyalg RSA -keysize 2048
-keystore keystore.p12 -validity 3650
2. Включите HTTPS в Spring Boot, добавив некоторые свойства в файл application.properties.
server.port: 8443
server.ssl.key-store: keystore.p12
server.ssl.key-store-password: mypassword
server.ssl.keyStoreType: PKCS12
server.ssl.keyAlias: tomcat
3. Перенаправить HTTP на HTTPS (необязательно). Я проигнорировал эту часть.
Но когда я запускаю свое приложение, у меня возникает такая ошибка:
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
По сути, это сообщение:
Private key must be accompanied by certificate chain.
Это самозаверяющий сертификат, поэтому у него, конечно же, нет доверенной цепочки. Как я могу это исправить?
Вот мой текущий файл application.properties:
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
Спасибо большое за вашу помощь.




Проблема в том, что в вашем сгенерированном хранилище ключей у вас нет пары ключей, поэтому нет закрытого ключа, потому что вы используете параметр -genkey, вам нужно изменить его с помощью параметра -genkeypair:
-genkey generates a Secret Key whereas the -genkeypair generates a key pair (a public key and a private key).
Поэтому я думаю, что это должно сработать:
keytool -genkeypair -alias tomcat -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 3650
В вашей весенней конфигурации загрузки измените ":" на "=" и добавьте путь к вашему хранилищу ключей, я полагаю, что ваш keystore.p12 находится в папке ресурсов, поэтому:
server.ssl.key-store = classpath:keystore.p12
server.ssl.key-store-password = mypassword
server.ssl.key-store-type = PKCS12
server.ssl.key-alias = tomcat
Я обновляю свой ответ, в настройках вашей пружины conf change ":" by " = " и добавляю путь к вашему хранилищу ключей для параметра "server.ssl.key-store"
Фактически, я использую «=» и «путь к классам» в своей конфигурации. Я попробовал оба способа, но ошибка все еще существует ...
Я обновляю свой ответ снова, есть другая проблема, снова измените "server.ssl.keyStoreType" = PKCS12 на "server.ssl.key-store-type = PKCS12"
Я только что обновил свой вопрос, чтобы добавить свою конфигурацию. Я заметил, что поле пароля должно быть key-store-password, как у вас. Поменял, работает !!! Вы можете обновить свой ответ (key-alias). Отмечу ваш ответ как правильный. Спасибо :)
Мое приложение не дает мне исключения, но через http браузер сообщает Bad Request This combination of host and port requires TLS, а через https говорит NET::ERR_CERT_AUTHORITY_INVALID. Что мне тогда делать?
Я также получал эту ужасную ошибку Private key must be accompanied by certificate chain в моем приложении Spring Boot со встроенным сервером Tomcat. Это делало меня безумный.
Оказывается, моей проблемой была простая опечатка:
@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);
}
Таким образом, сообщение об ошибке бесполезно вообще в этом случае. Надеюсь, это поможет кому-то другому. Просто убедитесь, что вы поместили правильные пароли (ключ против хранилища ключей) в нужное место. Та же проблема может возникнуть при настройке на основе свойств - это зависит от того, с чем вы работаете.
У меня такая же проблема. Я внес изменения из 2-го ответа. Но проблема не исчезла. После всего, что я сделал, я просто включил свой сертификат keystore.p12 в pom.xml в разделе профили
<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>
1. используйте "-genkeypair"
keytool -genkeypair -alias tomcat -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 3650
+1 за вторую часть. Я думаю, что в более поздней версии Springboot было некоторое переименование, но, к сожалению, сообщение об ошибке ничего не говорит о невозможности правильно прочитать пароль.
Вы допустили небольшую ошибку в файле application.properties. Пожалуйста измените
server.ssl.key-password=your_password
к
server.ssl.key-store-password=your_password
Тогда он будет работать нормально. Надеюсь, поможет! Спасибо!
Спасибо, только это изменение решило мою проблему. До сих пор не знаю, почему, потому что у меня была еще одна самозаверяющая сертификация, и с server.ssl.key-password=your_password работал ...
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
У меня была аналогичная проблема, в моем случае мне не хватало trustAnchors в хранилище доверенных сертификатов.
Одно из решений - использовать встроенный java keytool, как описано в других ответах. Но есть даже самый простой подход с использованием графического интерфейса KeyStore Explorer, поэтому я объясню полные шаги с обоими инструментами.
1. Прежде всего, как описано в ответе, нам нужно включить SSL в файле application.properties:
# <======= 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
# <=====================>
Хранилище ключей - это контейнер пары открытый - закрытый ключ, который используется сервером для безопасного взаимодействия с клиентами. У клиента, конечно же, должен быть открытый ключ, чтобы иметь возможность общаться с сервером.
Trust Store - это просто контейнер для сертификатов. (Открытые ключи). В нашем случае он будет содержать только один сертификат, используемый сервером.
2.1 Создайте хранилище ключей с java keytool:
keytool -genkeypair -alias alias -keyalg RSA -keysize 2048 -storetype PKCS12 -keystore keystore.p12 -validity 3650
2.2 Экспортируйте сертификат, чтобы мы могли использовать его для создания хранилища ключей Trust Store.
keytool -export -keystore keystore.p12 -alias alias -file certificate.cer
2.3 На этом шаге автоматически создается новое хранилище ключей с импортированным доверенным сертификатом. (Инструмент спросит у вас пароль для нового набора клавиш, и когда он спросит «Доверять этому сертификату?», Конечно, вы должны ввести «да»)
keytool -importcert -file certificate.cer -keystore trust_store.p12 -alias alias
Наконец, сохраните оба хранилища ключей в папке ресурсов вашего приложения Spring Boot (как показано в альтернативном подходе).
Альтернативный подход с KeyStore Explorer
2.1 Создайте хранилище ключей с помощью KeyStore Explorer, как показано на снимках экрана:






Затем сохраните хранилище ключей в папке ресурсов вашего приложения Spring Boot:

2.2 Теперь нам нужно создать хранилище доверенных сертификатов, которое может быть предоставлено клиенту, которому необходимо взаимодействовать с нашим сервером. Прежде всего извлеките цепочку сертификатов, созданную KeyStore Explorer, а затем создайте новое хранилище ключей, импортируя сертификат внутри него, как показано на снимках экрана:
Затем, чтобы создать наше хранилище доверенных сертификатов, нажмите «Создать новое хранилище ключей» в формате PKCS12, как на предыдущих шагах, нажмите красный значок «Импортировать доверенный сертификат», выберите сертификат, сохраненный на предыдущем шаге, и, наконец, сохраните хранилище ключей. внутри папки ресурсов, как мы это делали при создании первого хранилища ключей.
Теперь ваш сервер будет иметь возможность обмениваться данными с безопасностью SSL. Помните, что ваши клиенты должны быть настроены для загрузки созданного вами хранилища доверенных сертификатов.
Спасибо, но у меня все та же проблема :(