Я разрабатываю приложение Java, которое запрашивает REST API на удаленном сервере через HTTP. По соображениям безопасности эту связь следует переключить на HTTPS.
Теперь, когда Let's Encrypt запустил публичную бета-версию, я хотел бы знать, работает ли Java в настоящее время (или подтверждено, что будет работать в будущем) с их сертификатами по умолчанию.
Let's Encrypt получил свою промежуточную перекрестную подпись от IdenTrust , что должно быть хорошей новостью. Однако я не могу найти ни одного из этих двух в выводе этой команды:
keytool -keystore "..\lib\security\cacerts" -storepass changeit -list
Я знаю, что доверенные центры сертификации могут быть добавлены вручную на каждую машину, но поскольку мое приложение должно быть бесплатным для загрузки и исполняться без какой-либо дополнительной настройки, я ищу решения, которые работают «из коробки». У тебя есть для меня хорошие новости?
Ответы:
[ Обновление 2016-06-08 : согласно https://bugs.openjdk.java.net/browse/JDK-8154757, удостоверяющий центр IdenTrust будет включен в Oracle Java 8u101.]
[ Обновление от 05.08.2016 : выпущена Java 8u101, которая действительно включает в себя IdenTrust CA: примечания к выпуску ]
Да. Сертификат Let's Encrypt - это обычный сертификат открытого ключа. Java поддерживает его (согласно Let's Encrypt Certificate Compatibility для Java 7> = 7u111 и Java 8> = 8u101).
Нет / это зависит от JVM. Хранилище доверенных сертификатов Oracle JDK / JRE до 8u66 не содержит ни CA Let's Encrypt, ни удостоверяющего личность центра сертификации, который подписал его перекрестно.
new URL("https://letsencrypt.org/").openConnection().connect();
например приводит кjavax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException
.Однако вы можете предоставить свой собственный валидатор / определить собственное хранилище ключей, которое содержит требуемый корневой ЦС, или импортировать сертификат в хранилище доверенных сертификатов JVM.
https://community.letsencrypt.org/t/will-the-cross-root-cover-trust-by-the-default-list-in-the-jdk-jre/134/10 также обсуждает эту тему.
Вот пример кода, который показывает, как добавить сертификат в хранилище доверенных сертификатов по умолчанию во время выполнения. Вам просто нужно добавить сертификат (экспортированный из firefox как .der и вставленный в путь к классам)
На основе Как я могу получить список доверенных корневых сертификатов в Java? и http://developer.android.com/training/articles/security-ssl.html#UnknownCa
источник
isrgrootx1.der
иlets-encrypt-x1-cross-signed.der
, но ни один из них не подходит.https://helloworld.letsencrypt.org
например, к и проверьте цепочку сертификатов в браузере (щелкнув зеленый значок). Для этого вам понадобится сертификат для конкретного сайта, промежуточный сертификат X1 (перекрестная подпись IdenTrust) или сертификат DSTRootCAX3.ISRG Root X1
Не работает на сайте HelloWorld , потому что это не в цепочке, которая является альтернативой цепи. Я бы использовал DSTRoot, просто экспортированный через браузер, потому что я нигде не видел его для загрузки.javax.net.ssl.trustStore
системное свойство, но -1 для последующей установки JVM по умолчаниюSSLContext
. Было бы лучше создать новый,SSLSocketFactory
а затем использовать его для различных подключений (напримерHttpUrlConnection
), чем заменять конфигурацию SSL для всей виртуальной машины. (Я понимаю, что это изменение эффективно только для работающей JVM и не сохраняется и не влияет на другие программы. Я просто думаю, что лучше четко указать, где применяется ваша конфигурация.)Я знаю, что OP запросил решение без изменений локальной конфигурации, но если вы хотите добавить цепочку доверия в хранилище ключей навсегда:
источник: https://community.letsencrypt.org/t/will-the-cross-root-cover-trust-by-the-default-list-in-the-jdk-jre/134/13
источник
Подробный ответ для тех из нас, кто хочет внести локальные изменения конфигурации, включая резервное копирование файла конфигурации:
1. Перед внесением изменений проверьте, работает ли он.
Если у вас еще нет тестовой программы, вы можете использовать мою программу ping java SSLPing, которая проверяет рукопожатие TLS (будет работать с любым портом SSL / TLS, а не только с HTTPS). Я буду использовать предварительно созданный SSLPing.jar, но прочитать код и собрать его самостоятельно - это быстрая и простая задача:
Поскольку моя версия Java более ранняя, чем 1.8.0_101 (на момент написания этой статьи не выпущена), сертификат Let's Encrypt по умолчанию не проверяется. Давайте посмотрим, как выглядит сбой, прежде чем применять исправление:
2. Импортируйте сертификат.
Я использую Mac OS X с установленной переменной среды JAVA_HOME. Более поздние команды будут предполагать, что эта переменная установлена для изменяемой установки Java:
Сделайте резервную копию файла cacerts, который мы будем изменять, чтобы вы могли отменить любые изменения без переустановки JDK:
Загрузите сертификат подписи, который нам нужно импортировать:
Выполните импорт:
3. Убедитесь, что после изменений он работает.
Убедитесь, что Java теперь успешно подключается к порту SSL:
источник
Для JDK, которые еще не поддерживают сертификаты Let's Encrypt, вы можете добавить их в JDK
cacerts
после этого процесса (благодаря этому ).Загрузите все сертификаты на https://letsencrypt.org/certificates/ (выберите формат der ) и добавьте их один за другим с помощью такой команды (пример для
letsencryptauthorityx1.der
):источник