Альтернативное имя субъекта должно иметь схему для работы в Java? - PullRequest
0 голосов
/ 05 января 2019

У меня есть сертификат SSL с расширением SAN, имеющий домены типа:

  • foo.com
  • bar.foo.com
  • something.foo.com

Я добавил этот сертификат в cacerts и попытался подключиться к bar.foo.com с помощью http-клиента apache. Неожиданно я получил исключение:

Unparseable SubjectAlternativeName extension due to java.io.IOException: URI name must include scheme:foo.com

, что привело меня к sun.security.x509.URIName строке 112 класса: https://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/sun/security/x509/URIName.java#l112

if (uri.getScheme() == null) {
    throw new IOException("URI name must include scheme:" + name);
}

Для меня это означает, что домены SAN должны иметь схему, прежде чем фактический домен будет действительным. Похоже, это должно быть:

и действительно, когда я заменяю домен во время отладки кода, все работает нормально!

Так, может, сертификат, который я получил, не верен? Я посмотрел на сертификат Stackoverflow и что я вижу? StackOverflow cert Домены SAN также здесь без схемы, поэтому я думаю, что они правильные.

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

Я нашел следующие записи об ошибках Java:

где люди утверждают, что это действительно ошибка, но эти записи 15 ЛЕТ - они 2003-2004 гг.

Понятно, что я делаю что-то не так, поскольку невозможно, чтобы в Java была эта ошибка так долго

EDIT: Обратите внимание, что похожая ошибка появляется, когда я использую keytool для просмотра сертификата:

keytool -list -keystore truststore.jks -v

(...)

#10: ObjectId: 2.5.29.17 Criticality=false
Unparseable SubjectAlternativeName extension due to
java.io.IOException: URI name must include scheme:foo.com

1 Ответ

0 голосов
/ 05 января 2019

Существует несколько типов имен SAN. В TLS используются только dnsName имена типов (ipAddress используются очень редко). dnsName тип имени включает только часть домена без какой-либо схемы URI.

Ссылка, на которую вы ссылаетесь ( URIName.java ), говорит о другом типе имени SAN, называемом uriName, который действительно должен включать схему протокола. Этот тип имени обычно используется для представления URL-адресов к ресурсам CRT / CRL / OCSP в сертификатах и ​​CRL. И uriName не используется для аутентификации. Так что вам действительно нужен этот тип имени: DNSName.java

...