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

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

Я генерирую jssecacerts с recommendet сценарием: 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 EMAILADDRESS=info@plesk.com, CN=plesk, OU=Plesk, O=Parallels, L=Hernd
on, ST=Virginia, C=US
   Issuer  EMAILADDRESS=info@plesk.com, 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

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 64 бита

43
задан Bill the Lizard 3 August 2012 в 00:05
поделиться

1 ответ

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

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

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

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

  • если это не так, последний CN вашего subject distinguished name (это основное имя, если хотите) соответствует имени хоста. (См. RFC 2818.)

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

EMAILADDRESS=info@plesk.com, 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, только имя хоста).

62
ответ дан 26 November 2019 в 22:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: