Мы используем собственный протокол через сокеты. С TLS мы не можем использовать setEndpointIdentificationAlgorithm()
, поскольку его аргументы могут быть HTTPS или LDAPS.
Как выполнить проверку имени хоста в случае пользовательских протоколов?
Нужно ли нам использовать класс HostnameVerifier
, переопределяя метод verify()
? Если да, то как мы можем получить имя хоста из URL-адреса специального протокола?
Должно быть возможно получить конечный сертификат, и тогда вы сможете получить доступ к правильным элементам. Проблема в том, что я забыл, как это сделать на Java:/
Я вижу два «близких голосования», вероятно, от людей, которые не понимают вопроса. Если чего-то не хватает, пожалуйста, прокомментируйте.
Если вы используете собственный базовый протокол, отличный от HTTP, я думаю, в конечном итоге вы устанавливаете соединение javax.net.ssl.SSLSocket
. SSLSocket имеет getSSLSession() , который дает вам SSLSession, к которому можно запросить различные сведения о соединении SSL/TLS.
Кроме того, SSLSession — это именно то, что HostnameVerifer необходимо для проверки хоста. Таким образом, вы сможете использовать HttpsURLConnection.getDefaultHostnameVerifier()
, чтобы получить экземпляр верификатора по умолчанию, и использовать его для проверки, соответствует ли имя хоста, которое вы использовали для установления соединения, сертификату сервера.
Поэтому после установления соединения SSLSocket должна быть возможность проверить имя хоста таким образом (код не проверялся):
String hostname = "example.org";
SSLSocket socket = ... // establish SSLSocket to <hostname>
HostnameVerifier verifier = HttpsURLConnection.getDefaultHostnameVerifier();
verifier.verify(hostname, socket.getSession());
С пользовательским протоколом вы предоставлены сами себе. Проверка имени хоста AFAIK не встроена в TLS как таковую, но поставляется с протоколами более высокого уровня. Если у вас есть собственный протокол и он его не поддерживает, вам придется обойтись без него или добавить его. Однако вы сможете получить много вдохновения от HTTP.