2016-02-12 13 views
6

Dokumentacja Oracle wydaje się wskazywać, że Java 8 wysyła automatycznie i domyślnie SNI. Wireshark wskazuje inaczej. Jestem sysadminem PowerShell, a nie programistą Java, więc prawie pewne, że coś przeoczyłem.W języku Java 8 można uzyskać połączenie HTTP do wysłania nazwy serwera (SNI)

W przypadku użycia z odpowiednim magazynem kluczy zaufania następujący kod zwraca status 200 ze wszystkich witryn SSL, które nie wymagają SNI. Zwraca również dobrze podczas łączenia się z domyślną witryną SSL serwera hosta o wielu hostach. Jednak w przypadku prośby o połączenie z witryną inną niż domyślna nie można uzyskać nazwy certyfikatu niezgodnej z nazwą witryny, ponieważ łączy się ona z domyślną witryną.

import java.util.*; 
import java.net.*; 
import javax.net.ssl.*; 
import java.io.*; 

public class testJavaHttpConn { 
    public static void main(String[] args) throws Exception { 
     String strUrl = args[0]; 
     System.out.println("Trying to connect to " + strUrl); 
     try { 
      URL url = new URL(strUrl); 
      HttpsURLConnection urlConn = (HttpsURLConnection) url.openConnection(); 
      System.out.println("Connecting"); 
      urlConn.connect(); 
      System.out.println("Done"); 
      System.out.println("Response " + urlConn.getResponseCode()); 
     } catch (IOException e) { 
      System.err.println("Error creating HTTP connection"); 
      e.printStackTrace(); 
      throw e; 
     } 
    } 
} 

Mam nie zestaw System.setProperty ("jsse.enableSNIExtension", "false"); a kiedy ustawię - Djavax.net.debug = ssl, wyraźnie widać, że nie ustawiono rozszerzenia nazwy serwera.

Jestem świadomy, że mogę zaimplementować SSLSocket i ustawić nazwę serwera SSLParameter, jeśli chcę zanurkować do następnej głębszej warstwy abstrakcji, ale chciałbym tego uniknąć.

Edytuj: Kod działa tak, jak napisano powyżej dla Flo w komentarzach. Zawodzi mi w wersji 1.8.0_72 w systemie Linux 2.6.18-194.11.3.el5 i 1.8.0_51 w systemie Windows 7. Instalacja systemu Windows jest wanilią, podczas gdy instalacja systemu Linux zaktualizowała wartość parametru urandom do pliku securerandom.source = file: /dev/./urandom. Nie jestem pewien, w jaki sposób mogę określić, co o moich instalacjach różni się od Flo.

+0

Więc szukasz metodami innymi niż te, które [udokumentowane tutaj] (https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#SNIExtension)? –

+0

Jestem ograniczony ignorancją. Fragmenty kodu używające SSLSocket zakładają wiedzę do budowania wszystkich rzeczy poprzedzających i następujących, a ja ich nie mam. Nie znalazłem jeszcze przykładu pokazującego jak wykonać połączenie i odzyskać używając SSLSocket i przekonwertować wyjście do tego samego obiektu Zwraca HttpURLConnection. Zbudowałem wszystkie te obiekty na podstawie tych fragmentów, ale nie mogę nic z nimi zrobić, gdy je otrzymam. Biorąc pod uwagę moją niewiedzę, mądrze było zapytać, czy nie widzę prostej własności, która powoduje, że HttpsURLConnection wysyła sygnał SNI. Jeśli odpowiedź brzmi "nie", to jest to SSLSocket. – codepoke

+1

Przetestowałem Twój kod za pomocą "https://sni.velox.ch", a debugowanie mówi: "Rozszerzenie nazwa_serwera, nazwa_serwera: [type = nazwa_hosta (0), wartość = sni.velox.ch]". Powoduje to status 200. Z użyciem 'System.setProperty (" jsse.enableSNIExtension "," false ")' Otrzymuję błąd (zgodnie z oczekiwaniami) i brak jest rozszerzenia w debugowaniu. System: Ubuntu Linux, Java 1.8.0_72 (ale również pracował z 1.7.0_95). Niestety, nie mam dla ciebie rozwiązania. – flo

Odpowiedz

3

HttpsURLConnection robi wysłać Sni domyślnie po wyjęciu z pudełka IFF URL, do którego to podłączenie jest w pełni kwalifikowana nazwa. Nie wysyła SNI dla lokalnych aliasów skrótów w intranecie.

Extension server_name, server_name: [type=host_name (0), value=site.company.com] 

(Dla przypomnienia, Musiałem także wdrożyć nowy certyfikat z sieci SAN dla nazw krótkich iw pełni wykwalifikowanych, ale to było trywialne.)

Powiązane problemy