Как мне сделать проверку имени хоста при использовании JSSE?

Я пишу клиент на Java (должен работать как на настольном JRE, так и на Android) для проприетарного протокола (специфичного для моей компании), передаваемого по протоколу TLS. Я пытаюсь найти наилучший способ написания TLS-клиента на Java и, в частности, убедиться, что он правильно выполняет проверку имени хоста. (Редактировать: Под этим я подразумеваю проверку соответствия имени хоста сертификату X.509, чтобы избежать атак "человек посередине".)

JSSE является очевидным API для написания TLS-клиента, но я заметил изСамый опасный код в мире"Бумага (а также из экспериментов), что JSSE не проверяет имя хоста, когда используется SSLSocketFactory API. (Это то, что я должен использовать, так как мой протокол не HTTPS.)

Итак, похоже, что при использовании JSSE я должен сам выполнить проверку имени хоста. И вместо того, чтобы писать этот код с нуля (поскольку я почти наверняка понял бы его неправильно), кажется, что я должен «позаимствовать» некоторый существующий код, который работает. Итак, наиболее вероятный кандидат, который я нашел, это использовать библиотеку Apache HttpComponents (иронично, поскольку я на самом деле не делаю HTTP)и используйте класс org.apache.http.conn.ssl.SSLSocketFactory вместо стандартного класса javax.net.ssl.SSLSocketFactory.

Мой вопрос: это разумный курс действий? Или я совершенно неправильно понял, ушел из глубины, и на самом деле есть гораздо более простой способ проверки имени хоста в JSSE, без использования сторонней библиотеки, такой как HttpComponents?

Я также посмотрел на BouncyCastle, который имеет не-JSSE API для TLS, но кажется, что он еще более ограничен в том смысле, что он даже не выполняет проверку цепочки сертификатов, а тем более проверку имени хоста, поэтому он выглядел как не -стартер.

Редактировать: Этот вопросбыл дан ответ для Java 7, но мне все еще любопытно, какова «лучшая практика» для Java 6 и Android. (В частности, я должен поддерживать Android для моего приложения.)

Отредактировано снова: Чтобы сделать мое предложение «позаимствовать у Apache HttpComponents» более конкретным, я создалнебольшая библиотека который содержит реализации HostnameVerifier (прежде всего StrictHostnameVerifier и BrowserCompatHostnameVerifier), извлеченные из Apache HttpComponents. (Я понял, что все, что мне нужно, - это верификаторы, и мне не нужен SSLSocketFactory от Apache, как я изначально думал.) Если оставить это на усмотрение моих собственных устройств, это решение я буду использовать. Но, во-первых, есть ли причина, по которой яне должен сделать это так? (Предполагая, что моя цель состоит в том, чтобы сделать мою проверку имени хоста таким же образом, как это делает https. Я понимаю, что сама по себе открыта для обсуждения и обсуждалась в теме в списке криптографии, но сейчас я придерживаюсь HTTPS-подобного имени хоста проверка, хотя я не делаю HTTPS.)

Предполагая, что в моем решении нет ничего «неправильного», мой вопрос заключается в следующем: есть ли «лучший» способ сделать это, оставаясь переносимым на Java 6, Java 7 и Android? (Где «лучше» означает более идиоматический, уже широко используемый и / или требующий меньше внешнего кода.)

Ответы на вопрос(2)

Ваш ответ на вопрос