Jak powinienem sprawdzać nazwę hosta podczas korzystania z JSSE?

Piszę klienta w Javie (musi działać zarówno na pulpicie JRE, jak i na Androidzie) na własny protokół (specyficzny dla mojej firmy) przenoszony przez TLS. Próbuję dowiedzieć się, jak najlepiej napisać klienta TLS w Javie, aw szczególności upewnić się, że poprawnie sprawdza poprawność nazwy hosta. (Edytować: Mam tu na myśli sprawdzenie, czy nazwa hosta odpowiada certyfikatowi X.509, aby uniknąć ataków typu man-in-the-middle.)

JSSE jest oczywistym interfejsem API do pisania klienta TLS, ale zauważyłem „Najbardziej niebezpieczny kod na świecie„papier (a także z eksperymentów), że JSSE nie sprawdza poprawności nazwy hosta, gdy używa się API SSLSocketFactory. (Tego właśnie muszę używać, ponieważ mój protokół nie jest HTTPS).

Wygląda więc na to, że podczas korzystania z JSSE muszę wykonać walidację nazwy hosta. I zamiast pisać ten kod od zera (ponieważ prawie na pewno bym się pomylił), wydaje się, że powinienem „pożyczyć” jakiś istniejący kod, który działa. Więc najbardziej prawdopodobnym kandydatem, którego znalazłem, jest użycie biblioteki Apache HttpComponents (ironiczne, ponieważ tak naprawdę nie robię HTTP)i użyj klasy org.apache.http.conn.ssl.SSLSocketFactory zamiast standardowej klasy javax.net.ssl.SSLSocketFactory.

Moje pytanie brzmi: czy to rozsądny sposób działania? A może całkowicie źle zrozumiałem rzeczy, wyszedłem z głębszego końca i jest znacznie łatwiejszy sposób na sprawdzenie poprawności nazwy hosta w JSSE, bez wciągania biblioteki innej firmy, takiej jak HttpComponents?

Spojrzałem też na BouncyCastle, który ma interfejs API inny niż JSSE dla TLS, ale wydaje się być jeszcze bardziej ograniczony, ponieważ nie wykonuje nawet sprawdzania poprawności łańcucha certyfikatów, a tym bardziej sprawdzania nazw hostów, więc wydawało się, że nie -rozrusznik.

Edytować: To pytaniezostał odebrany dla Java 7, ale wciąż jestem ciekawy, co to jest „najlepsza praktyka” dla Java 6 i Androida. (W szczególności muszę obsługiwać Androida dla mojej aplikacji).

Zmieniono ponownie: Aby moja propozycja „pożyczyć od Apache HttpComponents” była bardziej konkretna, stworzyłemmała biblioteka który zawiera implementacje HostnameVerifier (w szczególności StrictHostnameVerifier i BrowserCompatHostnameVerifier) ​​wyodrębnione z Apache HttpComponents. (Zdałem sobie sprawę, że wszystko, czego potrzebuję, to weryfikatory, a ja nie potrzebuję Apache's SSLSocketFactory, jak początkowo myślałem.) Jeśli pozostawię to moim własnym urządzeniom, jest to rozwiązanie, którego użyję. Ale po pierwsze, czy jest jakiś powód, dla którego janie powinienem zrobić to w ten sposób? (Zakładając, że moim celem jest sprawdzenie poprawności nazwy hosta w taki sam sposób, jak robi to https. Zdaję sobie sprawę, że sama jest otwarta na debatę i została omówiona w wątku na liście kryptograficznej, ale na razie trzymam się nazwy hosta podobnej do HTTPS sprawdzanie poprawności, nawet jeśli nie robię HTTPS.)

Zakładając, że w moim rozwiązaniu nie ma nic „złego”, moje pytanie brzmi: czy istnieje „lepszy” sposób na to, a jednocześnie pozostanie przenośny w Javie 6, Java 7 i Androida? (Gdzie „lepszy” oznacza bardziej idiomatyczny, już powszechnie używany i / lub wymagający mniej kodu zewnętrznego).

questionAnswers(2)

yourAnswerToTheQuestion