2013-07-31 20 views
8

Czytam z gniazda SSL, ale host nie pasuje do certyfikatu (np. host = "localhost"). Spodziewam się wyjątku, ale poniższy kod bez problemu poradzi sobie z serwerem zdalnym.SSLSocket ignoruje niedopasowanie domeny

try (
    final Socket socket = SSLSocketFactory.getDefault().createSocket(host, port); 
    final OutputStream os = socket.getOutputStream(); 
    final InputStream is = socket.getInputStream()) { 

    os.write(("HEAD/HTTP/1.1\r\nHost: " + host + "\r\nConnection: close\r\n\r\n").getBytes()); 
    os.flush(); 

    final byte[] bytes = new byte[1024]; 
    int n; 
    while ((n = is.read(bytes)) != -1) { 
     System.out.print(new String(bytes, 0, n)); 
    } 
    System.out.println(); 
} catch (final IOException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} 

Dlatego próbowałem innego podejścia:

try { 
    final HttpURLConnection conn = (HttpURLConnection) new URL("https://" + host + ":" + port + "/").openConnection(); 

    try (InputStream is = conn.getInputStream()) { 
     IOUtils.copy(is, System.out); 
    } catch (final IOException e1) { 
     try (InputStream es = conn.getErrorStream()) { 
      if (es != null) { 
       IOUtils.copy(es, System.out); 
      } 
     } 
    } 
} catch (final IOException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} 

Niestety nadal nie dostaniesz wyjątek SSL, tylko WARN w dziennikach: 2013-07-31 16:02:27,182 WARN nio - javax.net.ssl.SSLException: Received fatal alert: certificate_unknown

Jak uzyskać wyjątek, jeśli certyfikat SSL nie pasuje?

Odpowiedz

16

Specyfikacja protokołu SSL/TLS jest modularna i odłączona od specyfikacji użytej do uwierzytelnienia zdalnego hosta. Te pozostałe specyfikacje są podzielone na dwie kategorie: sprawdzenie, czy sam certyfikat może być zaufany (RFC 3280/5280) i weryfikacja tożsamości w certyfikacie (RFC 6125 lub RFC 2818 dla HTTPS).

JSSE integruje protokół SSL i weryfikację certyfikatu w interfejsie API SSLSocket (lub SSLEngine), ale nie obsługuje weryfikacji identyfikatora (co jest równie ważne).

Wynika to głównie z faktu, że SSLSocket/SSLEngine może mieć zastosowanie do dowolnego protokołu aplikacji (np. HTTP, IMAP, SMTP, LDAP, ...), ale zasady weryfikacji identyfikatora były w różnych specyfikacjach (z małe odmiany), aż do RFC 6125 (który jest wciąż całkiem nowy).

obsługuje oba, ponieważ używa również parametru HostnameVerifier, który jest zgodny ze specyfikacją HTTPS (RFC 2818, sekcja 3.1). Odbywa się to niezależnie od interfejsu API SSLSocket/SSLEngine. W przypadku innych protokołów może zajść potrzeba implementacji specyfikacji protokołu.

W związku z tym, od czasu Java 7, istnieje mechanizm do weryfikacji tożsamości certyfikatu bezpośrednio w ramach interfejsu API SSLSocket/SSLEngine.

SSLParameters sslParams = new SSLParameters(); 
sslParams.setEndpointIdentificationAlgorithm("HTTPS"); 
sslSocket.setSSLParameters(sslParams); 

Użycie tego polecenia powinno spowodować zgłoszenie wyjątku, jeśli nazwa hosta nie jest zgodna.

Nie ma większych różnic między HTTPS a bardziej jednolitymi specyfikacjami w RFC 6125 (poza tym, że te ostatnie uwzględniają adresy IP poza zakresem). Nawet jeśli nie korzystasz z protokołu HTTPS, zazwyczaj warto używać jego specyfikacji identyfikacyjnych dla innych protokołów. (Być może algorytm identyfikacji punktu końcowego "RFC 6125" może pojawić się w późniejszych wersjach Java.)

+0

Dzięki za podanie szczegółów. –

2

Dopasowanie nazwy hosta nie jest częścią protokołu SSL, jest częścią protokołu HTTPS. Zobacz na przykład javax.net.ssl.HostnameVerifier.

Podany przez Państwa dziennik wskazuje, że wyodrębnienie pamięci SSLEx było generowane przez HttpsURLConnection.

+0

Po odnalezieniu tego loga dowiedziałem się, że jest on zalogowany w org.eclipse.jetty.io.nio.SelectChannelEndPoint' (ta próbka i serwer znajdują się na tej samej maszynie JVM). Również odkryłem, że 'wyjątek IOEx' wyrzucony z odczytu z connection.getInputStream() jest w rzeczywistości' javax.net.ssl.SSLHandshakeException' i to jest dokładnie to, czego potrzebuję :-) –

Powiązane problemy