Как разрешаются имена серверов сертификатов SSL/можно ли добавлять альтернативные имена с помощью keytool?
Они могут быть сформулированы как отдельные вопросы для ясности, но все они относятся к одному вопросу.
как разрешаются имена серверов сертификатов SSL?
Почему браузеры, похоже, используют поле CN сертификата, но механизм Java, похоже, смотрит только на "альтернативные имена субъектов"?
можно ли добавить альтернативные имена в сертификат SSL с помощью keytool? Если нет, то использует openSSL вместо хорошего вариант??
просто немного фона: мне нужно получить основной сервер для связи с несколькими серверами с помощью HTTPS. Очевидно, что мы не хотим покупать SSL-сертификаты для каждого сервера (их может быть много), поэтому я хочу использовать самозаверяющие сертификаты (я использую keytool для их создания). После того, как я добавляю сертификаты как доверенные в ОС, браузеры (IE и Chrome) с радостью принимают соединение как доверенное. Однако, даже после добавления сертификатов в Java cacerts, Java по-прежнему не будет принимать соединение как доверенное и выдает следующее исключение:
вызвано: java.безопасность.сертификат.CertificateException: нет альтернативных имен субъектов подарок в Sun.безопасность.утиль.HostnameChecker.matchIP (HostnameChecker.Ява:142) в Sun.безопасность.утиль.HostnameChecker.матч(HostnameChecker.на Java:75) на ком.солнце.чистая.протокол SSL.внутренние.протокол SSL.X509TrustManagerImpl.checkIdentity(X509T rustManagerImpl.java:264) на ком.солнце.чистая.протокол SSL.внутренние.протокол SSL.X509TrustManagerImpl.checkservertrusted методы( X509TrustManagerImpl.java: 250) на ком.солнце.чистая.протокол SSL.внутренние.протокол SSL.ClientHandshaker.serverCertificate(пре тандшейкер.java: 1185) ... Более 14
Я обнаружил, что могу заставить Java доверять сертификату, реализующему мой собственный HostNameVerifier, который я скопировал отсюда: com.солнце.ЖБИ.внутренний.безопасность.протокол https.DefaultHostnameVerifier просто для проверки (кстати, имя прошло в качестве аргумента для HostnameVerifier правильно, поэтому я думаю, что это должно было быть принято).
Я использую поле сертификата CN в качестве имени хоста (обычно IP-адрес).
может ли кто-нибудь сказать мне, если я делаю что-то неправильно и указать мне в правильном направлении?
1 ответ:
как проверка имени хоста должна быть выполнена определяется в RFC 6125, который совсем недавно и обобщает практику для всех протоколов, и заменяет RFC 2818, который был специфичен для HTTPS. (Я даже не уверен, что Java 7 использует RFC 6125, который может быть слишком недавним для этого.)
если расширение subjectAltName типа dNSName присутствует, это должно быть использован в качестве тождественность. В противном случае (наиболее конкретное) общее имя необходимо использовать поле в поле Тема сертификата. Несмотря на то использование общего имени-это существующая практика, она устарела и Центры сертификации рекомендуется использовать DNS-имя.
[...]
в некоторых случаях URI указывается как IP-адрес, а не a имя хоста. В этом случае iPAddress subjectAltName должен присутствовать в сертификате так и должно точно сопоставьте IP в URI.
по сути, конкретная проблема у вас возникает из-за того, что вы используете IP-адреса в своем CN, а не имя хоста. Некоторые браузеры могут работать, потому что не все инструменты строго следуют этой спецификации, в частности потому, что "наиболее конкретный" в RFC 2818 не определен четко (см. обсуждение в RFC 6215).
если вы используете
keytool
,С Java 7,keytool
есть возможность включить альтернативный предмет Имя (см. таблицу в документации для-ext
): вы могли бы использовать-ext san=dns:www.example.com
или-ext san=ip:10.0.0.1
.EDIT:
вы можете запросить SAN в OpenSSL, изменив
openssl.cnf
(он выберет копию в текущем каталоге, если вы не хотите редактировать глобальную конфигурацию, насколько я помню, или вы можете выбрать явное местоположение с помощьюOPENSSL_CONF
переменные среды).установите следующие параметры (найдите соответствующие разделы внутри скобки сначала):
[req] req_extensions = v3_req [ v3_req ] subjectAltName=IP:10.0.0.1 # or subjectAltName=DNS:www.example.com
есть также хороший трюк, чтобы использовать переменную среды для этого (а не фиксировать ее в файле конфигурации) здесь:http://www.crsr.net/Notes/SSL.html