CertificateException: имя, совпадающее с ssl.someUrl.de, не найдено

Я пытаюсь подключиться к одному из моих серверов через ssl, используя Java. Я перепробовал много вариантов, вот моя лучшая попытка:

Я создаю jssecacerts с помощью рекомендуемого сценария: http://blogs.oracle.com/andreas/resource/InstallCert.java с помощью команды: java InstallCert ssl.someUrl.de changeit

после этого я повторил команду:

Loading KeyStore jssecacerts...
Opening connection to ssl.someUrl.de:443...
Starting SSL handshake...

No errors, certificate is already trusted

Server sent 1 certificate(s):

 1 Subject [email protected], CN=plesk, OU=Plesk, O=Parallels, L=Hernd
on, ST=Virginia, C=US
   Issuer  [email protected], CN=plesk, OU=Plesk, O=Parallels, L=Hernd
on, ST=Virginia, C=US
   sha1    f1 0d 2c 54 05 e1 32 19 a0 52 5e e1 81 6c a3 a5 83 0d dd 67
   md5     f0 b3 be 5e 5f 6e 90 d1 bc 57 7a b2 81 ce 7d 3d

Enter certificate to add to trusted keystore or 'q' to quit: [1]

Я скопировал файл в каталог по умолчанию и загрузил сертификат в Java trustStore.

System.setProperty("javax.net.ssl.trustStore", "C:\\Program Files (x86)\\Java\\jre6\\lib\\security\\jssecacerts");
System.setProperty("javax.net.ssl.trustStorePassword","changeit");

Потом пытаюсь подключиться

URL url = new URL("https://ssl.someUrl.de/");
URLConnection conn = url.openConnection();
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));

И я получаю ошибку в 3-й строке: (Не найдено совпадения имени ssl.someUrl.de)

javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No name matching ssl.someUrl.de found

Это причина сертификата plesk по умолчанию или что-то еще не так?

Установка: JRE 6.20, Netbeans 6.8, Windows7 64bit


person fehrlich    schedule 22.06.2010    source источник


Ответы (8)


Похоже, сертификат сервера, к которому вы пытаетесь подключиться, не соответствует его имени хоста.

Когда клиент HTTPS подключается к серверу, он проверяет, совпадает ли имя хоста в сертификате с именем хоста сервера. Недостаточно доверять сертификату, он также должен соответствовать серверу, с которым вы хотите общаться. (По аналогии, даже если вы доверяете паспорту как законному, вам все равно необходимо проверить, что это тот, с которым вы хотите поговорить, а не просто паспорт, который вы считаете законным.)

В HTTP это делается путем проверки того, что:

  • сертификат содержит запись альтернативного имени субъекта DNS (это стандартное расширение), совпадающую с именем хоста;

  • в противном случае последний CN отличительного имени вашего субъекта (это главное имя, если хотите) совпадает с именем хоста. (См. RFC 2818.)

Трудно сказать, что такое альтернативное имя субъекта, не имея сертификата (хотя, если вы подключитесь к своему браузеру и проверите его содержимое более подробно, вы сможете его увидеть). Отличительное имя субъекта выглядит следующим образом:

[email protected], CN=plesk, OU=Plesk, O=Parallels, L=Herndon, ST=Virginia, C=US

(Таким образом, это должно быть CN = ssl.someUrl.de вместо CN = plesk, если у вас уже нет альтернативного имени субъекта с DNS: ssl.someUrl.de; я предполагаю, что у вас его нет.)

Вы можете обойти проверку имени хоста, используя HttpsURLConnection.setHostnameVerifier (..). Не должно быть слишком сложно написать собственный HostnameVerifier, который обходит проверку, хотя я бы посоветовал делать это только тогда, когда сертификат касается именно того, о котором идет речь. Вы должны иметь возможность получить это, используя аргумент SSLSession и его метод getPeerCertificates ().

(Кроме того, вам не нужно устанавливать свойства javax.net.ssl. * Так, как вы это сделали, поскольку вы все равно используете значения по умолчанию.)

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

person Bruno    schedule 22.06.2010
comment
спасибо, я сделал это с HostnameVerifier. Мне просто нужно зашифрованное соединение. Есть только один клиент и один сервер с фиксированным адресом htts: //. - person fehrlich; 22.06.2010
comment
Помните, что вам нужна какая-то форма подтверждения личности с помощью шифрования для обеспечения безопасности. В противном случае это похоже на обмен секретами с кем-то, кого вы не знаете: каким бы хорошим ни был метод секретности, на самом деле он вас не защищает. - person Bruno; 22.06.2010
comment
но я знаю сервер и единственный клиент (который находится на моем компьютере), и никто не может прочитать поток данных. И https-страница тоже защищена простым htaccess. Или я ошибаюсь? - person fehrlich; 22.06.2010
comment
Ну, это зависит от того, насколько вы уверены, что никто не сможет прочитать поток данных. Если вы чувствуете, что вам нужен SSL для защиты связи, тогда вам нужно убедиться, что удаленный сертификат - это тот, с которым вы хотите общаться. Создание исключения вручную, как вы делаете, - это нормально, но вам все равно нужно проверить, действительно ли это исключение, которое вы хотите сделать. - person Bruno; 22.06.2010
comment
@Bruno Я пытаюсь установить ssl в kafka с помощью localhost. Будет ли работать localhost? И что будет, если у меня есть IP-адрес системы, в которой я устанавливаю сертификаты. - person Himanshu; 06.09.2019

В Java 8 вы можете пропустить проверку имени сервера с помощью следующего кода:

HttpsURLConnection.setDefaultHostnameVerifier ((hostname, session) -> true);

Однако это следует использовать только в разработке!

person jaguililla    schedule 02.09.2014
comment
большое спасибо. дополнительная помощь здесь: mkyong.com/webservices/jax-ws/ - person OhadR; 28.03.2016
comment
Интересно, что @OhadR ответ не сработал, но ссылка, которой вы поделились, сработала. Я озадачен. Это нужно реализовать статическим способом? - person Davut Gürbüz; 02.12.2018

Я создал метод fixUntrustCertificate (), поэтому, когда я имею дело с доменом, не входящим в доверенные центры сертификации, вы можете вызвать этот метод до запроса. Этот код будет работать после java1.4. Этот метод применяется ко всем хостам:

public void fixUntrustCertificate() throws KeyManagementException, NoSuchAlgorithmException{


        TrustManager[] trustAllCerts = new TrustManager[]{
            new X509TrustManager() {
                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    return null;
                }

                public void checkClientTrusted(X509Certificate[] certs, String authType) {
                }

                public void checkServerTrusted(X509Certificate[] certs, String authType) {
                }

            }
        };

        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new java.security.SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

        HostnameVerifier allHostsValid = new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        };

        // set the  allTrusting verifier
        HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
}
person Cassio Seffrin    schedule 21.11.2015
comment
Я настраиваю обратный прокси для вызова другой службы https, и это решение решает все мои проблемы. В другом решении, помимо java.security.cert.CertificateException: не найдено совпадение имени imobileqaf.mobile.medcity.net, другое исключение появляется позже, например sun.security.provider.certpath.SunCertPathBuilderException: невозможно найти действительную сертификацию путь к запрошенной цели и java.security.InvalidAlgorithmParameterException: параметр trustAnchors не должен быть пустым. - person Liqun Sun; 05.03.2019
comment
Приятно знать, давно использую этот подход. Для производственной среды всегда лучше иметь действующий подписанный сертификат, хотя самоподписанные сертификаты намного лучше, чем ничего! - person Cassio Seffrin; 06.03.2019

Если вы ищете ошибку Kafka, это может быть связано с обновлением версии Kafka с 1.x до 2.x.

javax.net.ssl.SSLHandshakeException: общая проблема SSLEngine ... javax.net.ssl.SSLHandshakeException: общая проблема SSLEngine ... java.security.cert.CertificateException: совпадение имен не найдено ***

or

[Производитель clientId = продюсер-1] Соединение с узлом 2 не прошло аутентификацию из-за сбоя установления связи SSL.

Значение по умолчанию для ssl.endpoint.identification.algorithm было изменено на https, который выполняет проверку имени хоста (в противном случае возможны атаки типа «человек посередине»). Задайте для ssl.endpoint.identification.algorithm пустую строку, чтобы восстановить предыдущее поведение. Apache Kafka Заметные изменения в 2.0.0

Решение: SslConfigs.SSL_ENDPOINT_IDENTIFICATION_ALGORITHM_CONFIG, ""

person Senchan Sue    schedule 08.04.2019
comment
Итак, сегодня я боролся с этим весь день, я уже добавил ssl.endpoint.identification.algorithm в server.properties, но каждый раз, когда я хотел использовать потребителя или производителя, то есть ./kafka-console-producer.sh - broker-list fs: 9094 --topic test --producer.config ../config/producer.properties с, конечно, ssl-свойствами в consumer.properties для клиента jks и т. д. Я все еще получал ошибку, поэтому я решил бросьте вышеуказанный ssl.endpoint.identification.algorithm в consumer.properties, и он, похоже, исправил его. - person tosi; 02.08.2019
comment
Спасибо, что разместили это .. Я могу здесь из-за проблемы с кафкой ... - person Manu Mukerji; 04.12.2020

Я нашел здесь хорошее разрешение: http://www.mkyong.com/webservices/jax-ws/java-security-cert-certificateexception-no-name-matching-localhost-found/

Но моя проблема была немного другой и решила ее по-другому.

Веб-служба находилась на удаленном хосте. Например: https://some.remote.host/MyWebService?wsdl.

Но для любых клиентов он был доступен только по IP, а сертификат был создан для домена: some.remote.host (CN = some.remote.host). И этот домен не может быть разрешен по IP, потому что он не представлен в DNS).

Итак, возникла та же проблема: если я использую IP для подключения к веб-сервису по ssl, он не может быть достигнут, потому что сертификат CN = some.remote.host не равен указанному мной имени хоста (т.е. IP хоста) .

Я решил это, сопоставив это имя хоста с IP в файле / etc / hosts. Проблема была устранена.

Но в случае, когда веб-сервис размещен на сервере приложений localhost, он считает, что это должно быть решено, как mkyong, описанный в его статье.

person Zaur_M    schedule 10.07.2013

Имя сервера должно совпадать с именем / фамилией, которое вы даете при создании сертификата.

person user2181029    schedule 25.07.2013

В случае, если это кому-то поможет:

Пример использования: я использую самозаверяющий сертификат для разработки на localhost.

Ошибка: Причина: java.security.cert.CertificateException: имя, соответствующее локальному хосту, не найдено

Решение. Когда вы создаете самозаверяющий сертификат, убедитесь, что вы ответили на этот вопрос следующим образом (см. ответ Бруно, чтобы узнать, почему):

What is your first and last name?
  [Unknown]:  localhost



В качестве бонуса вот мои шаги:
1. Создать самозаверяющий сертификат:

keytool -genkeypair -alias netty -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 4000
Enter keystore password: ***
Re-enter new password: ***
What is your first and last name?
  [Unknown]:  localhost
...

2. Скопируйте сертификат в src / main / resources (при необходимости)

3. Обновите cacerts
keytool -v -importkeystore -srckeystore keystore.p12 -srcstoretype pkcs12 -destkeystore "% JAVA_HOME% \ jre \ lib \ security \ cacerts" -deststoretype jks

4. Обновите свою конфигурацию (в моем случае application.properties):

server.port=8443
server.ssl.key-store=classpath:keystore.p12
server.ssl.key-store-password=jumping_monkey
server.ssl.key-store-type=pkcs12
server.ssl.key-alias=netty



Ура

person jumping_monkey    schedule 31.01.2020

можно пропустить проверку имени хоста, установив свойство виртуальной машины:

-Djdk.internal.httpclient.disableHostnameVerification

Это работает с реализацией Java 11 HttpClient.

person Rahul Goyal    schedule 19.04.2021
comment
Дала шанс Java 8, но не удалось. :) - person Taner; 25.06.2021