Использовать ssl-сертификат в весеннем загрузочном приложении

Я следовал учебнику это по использованию самозаверяющего сертификата, и до сих пор это работало.

Затем я купил 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

Что я делаю неправильно?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Версия Java на основе версии загрузки
Версия Java на основе версии загрузки
Если вы зайдете на официальный сайт Spring Boot , там представлен start.spring.io , который упрощает создание проектов Spring Boot, как показано ниже.
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
2
0
7 969
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Если вы используете maven, это, вероятно, происходит из-за фильтрации Maven во всей папке ресурсов. Фильтрация ресурсов Maven (которая позволяет вам включать переменные в ваши файлы ресурсов) может испортить ваши двоичные файлы, а сертификаты особенно чувствительны к модификации.

Подробнее о фильтрации ресурсов maven: http://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html

Ответ принят как подходящий

Во-первых, вы, похоже, используете 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, или вообще любой доказывающий, должен иметь запись «закрытого ключа», содержащая cert И соответствующий PRIVATEKEY И обычно CHAIN ​​CERT(S). Чтобы быть точным, стандарты TLS требуют, чтобы сервер отправлял/все сертификаты цепи, необходимые для проверки сертификата объекта=сервера, необязательно исключая корень или привязку; JSSE обычно отправляет сертификаты, которые находятся в PrivateKeyEntry, поэтому вы должны поместить туда необходимые сертификаты. Для любого общедоступного ЦС (например, Verisign^WSymantec^WDigicert, GoDaddy, LetsEncrypt/Identrust) примерно с 1990 года требуется по крайней мере один сертификат цепи, иногда два и очень редко больше. Для частного ЦС это может варьироваться в зависимости от ЦС. Если сервер не отправляет необходимые сертификаты цепочки, клиенты немного все еще могут проверять сертификаты немного; в частности, браузеры часто могут «заполнять» отсутствующие сертификаты цепочки из общедоступных ЦС. Это создает ситуацию, когда некоторые соединения с вашим сервером выполняются успешно, в то время как другие соединения с тем же сервером терпят неудачу, что, как правило, очень сбивает с толку и расстраивает пользователей, и не рекомендуется.

Если ваш файл .key на самом деле содержит только сертификат, его название .key вводит в заблуждение и сбивает с толку. Если он содержит сертификат и ключ тогдав ПОМ, Java может прочитать и отделить часть сертификата и игнорировать ключ; это позволяет запускать keytool, но создает результирующий файл, который Tomcat не может использовать для приема соединений TLS/SSL. (В зависимости от версии и, возможно, конфигурации, он может генерировать достаточно конкретное исключение, такое как «не ключ» или «ключ не найден», или он может просто отклонить все попытки подключения с помощью handshake_failure.) Если он содержит только ключ или ключ, то сертификат или не PEM, команда keytool завершится ошибкой, а ваша, по-видимому, нет.

keytool не может импортировать закрытый ключ из чего-либо, кроме (другого) поддерживаемого хранилища ключей, что не очень вам поможет, потому что, если он уже находится в хранилище ключей, вам не нужно его импортировать. Ваш выбор:

  • если у вас есть командная строка openssl, используйте ее для преобразования ключа + сертификата(ов) в PKCS12. (openssl pkcs12 -export будет включать сертификат(ы) цепочки, если вы предоставите его/их явно или явно укажете -chain и предоставите или по умолчанию хранилище доверенных сертификатов, содержащее его/их.) Существуют десятки существующих вопросов и ответов стека, уходящих много лет назад, охватывающих этот обычная и популярная альтернатива.

  • используйте keytool для генерировать пары ключей (уже в формате хранилища ключей, поддерживаемого Java) и CSR, и получите сертификат, выданный для это CSR, а затем используйте keytool -import либо (1) импортировать сертификаты цепочки ЦС как доверенные, а тогда — сертификат сервера к существующей записи закрытого ключа, который автоматически заполняет цепочку или (2) импортирует всю цепочку CA напрямую к существующей записи закрытого ключа. В этой альтернативе также есть много существующих вопросов и ответов, а также собственный документ Sun / Oracle для Java и адаптированные версии из каждого CA (или почти так).

  • напишите или найдите и используйте программу, которая явно загружает закрытый ключ и сертификат (ы) из любого формата (ов), которые у вас есть, в запись «закрытый ключ» в поддерживаемом хранилище ключей. Это больше работы, и есть только несколько вопросов и ответов по этому поводу.

Должен признаться, что я весьма далек от всего этого и не понимаю деталей. Наконец, этот пост в сочетании с stackoverflow.com/questions/17695297/… помог мне, и у меня все заработало.

tobi 20.04.2019 10:17

Столкнулся с этой ошибкой во время приложения Spring Boot с запуском сертификата PCKS12. Простое повышение версии Java с 8 до 11 исправило ошибку. Имейте в виду, что все используемые вами классы должны быть в обеих версиях Java.

как насчет прямого запуска из 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

Другие вопросы по теме