java.security.cert.CertificateException: не найдено альтернативных имен субъектов, соответствующих IP-адресу xxxx - PullRequest
0 голосов
/ 05 мая 2019

У меня есть Java-программа, которая пытается загрузить файл с IP-адреса.Допустим, IP-адрес 10.2.14.35.Итак, файл расположен в https://10.2.14.35/path/to/the/file/myfile.txt. У меня есть следующая функция, которая предназначена для загрузки этого файла:

public static void downloadFile(String uri, String localFileName) {
  try {
    URL url = new URL(uri);
    ReadableByteChannel readableByteChannel = Channels.newChannel(url.openStream());
    FileOutputStream fileOutputStream = new FileOutputStream(localFileName);

    fileOutputStream
        .getChannel()
        .transferFrom(readableByteChannel, 0 /* position */, Long.MAX_VALUE /* count */);

    fileOutputStream.close();
    readableByteChannel.close();
  } catch (IOException e) {
    throw new AgentException(ErrorProto.Type.kIOError, e.getMessage());
  }
}

И использование функции как:

downloadFile(" https://10.2.14.35/path/to/the/file/myfile.txt", "/tmp/myfile.txt")

Я получаю ошибку java.security.cert.CertificateException: No subject alternative names matching IP address 10.2.14.35 found.Я обнаружил, что некоторые вопросы задавались по SO ( JAVA - альтернативные имена субъектов не соответствуют IP-адресу , SSLHandshakeException: альтернативные имена субъектов отсутствуют , Как разрешаются имена серверов сертификатов SSL /Могу ли я добавить альтернативные имена с помощью keytool? ), но ни одно из них не сработало (или, может быть, я где-то что-то делал не так.)

Из браузера я попытался загрузить файл, и он был загружен.Однако это показывало, что сайт не защищен, потому что сертификат недействителен.Я не уверен, что из-за этого не удалось загрузить файл через java-программу.При чтении я натолкнулся на концепцию cacerts, и я должен заставить JRE понять, что нормально подключаться к 10.2.14.35.Для этого мне нужно создать сертификат и импортировать его в cacerts.Я сделал это, но это не сработало, потому что, может быть, я что-то пропустил.Может ли кто-нибудь помочь мне указать на ошибку?

Ответы [ 2 ]

1 голос
/ 05 мая 2019

TLDR

Ошибка, которую вы видите, связана с конкретным расширением сертификата, называемым Subject Alternative Name, в котором 10.2.14.35 не указан в качестве действительного IP-адреса.

Ошибка такжеуказывает, что сертификат CA уже является доверенным.Если ЦС не был доверенным, проверка сертификата провалилась бы раньше и вызвала бы другую ошибку, что-то вроде

Построение пути PKIX не удалось: sun.security.provider.certpath.SunCertPathBuilderException: невозможно найти допустимый путь сертификациик запрошенной цели


Поскольку у меня нет доступа к вашему конкретному сертификату, я попытаюсь проиллюстрировать, используя сертификат сервера example.com.

Для просмотра сертификата яЯ буду использовать openssl , но доступно несколько других инструментов - например, большинство браузеров могут отображать детали сертификата.

Я удалю вывод, который, как мне кажется, не нужен для иллюстрациичто я хочу

$ openssl s_client -connect example.com:443 -showcerts | openssl x509 -noout -text
[...]
Subject: C = US, ST = California, L = Los Angeles, O = Internet Corporation for Assigned Names and Numbers, OU = Technology, CN = www.example.org
[...]
    X509v3 Subject Alternative Name: 
       DNS:www.example.org, DNS:example.com, DNS:example.edu, DNS:example.net, DNS:example.org, DNS:www.example.com, DNS:www.example.edu, DNS:www.example.net

Поле Subject содержит различные виды информации, но значение CN (Common Name) - www.example.com.Ранее большинство или все браузеры использовали это для проверки того, что сертификат был выдан для сервера, к которому был подключен браузер.Однако, более поздняя версия Chrome (и я думаю, что Firefox) полностью игнорирует информацию в поле Subject и вместо этого использует Subject Alternative Name.

Для Chrome 58 ипозже для сопоставления имени домена и сертификата сайта используется только расширение subjectAlternativeName, а не commonName.Альтернативное имя субъекта сертификата может быть доменным именем или IP-адресом.Если сертификат не имеет правильного расширения subjectAlternativeName, пользователи получают ошибку NET :: ERR_CERT_COMMON_NAME_INVALID, сообщающую им, что соединение не является частным.

Итак, ваша ошибка связана с тем, чтосертификат сервера, представленный 10.2.14.35, не содержит IP-адрес, к которому вы подключаетесь.Если посмотреть на сертификат с использованием openssl, сертификат, представленный сервером, должен иметь по крайней мере Subject Alternative Name, и он должен содержать по крайней мере IP Address:10.2.14.35.Построенный минимальный пример будет выглядеть примерно так.

$ openssl s_client -connect 10.2.14.35:443 -showcerts | openssl x509 -noout -text
[...]
Subject: CN = 10.2.14.35
[...]
    X509v3 Subject Alternative Name: 
        IP Address:10.2.14.35
0 голосов
/ 05 мая 2019

Однако показывалось, что сайт небезопасен, поскольку сертификат недействителен. Я не уверен, что из-за этого не удалось загрузить файл через java-программу.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...