2011-12-17 19 views
6

Czy ktoś wie o dobrych tutorialach, witrynach i książkach dotyczących pisania sprawdzania SSL w Javie? Próbuję zrobić to, co można znaleźć tutaj: http://www.sslshopper.com/ssl-checker.html. Nie próbuję utworzyć samopodpisanego certyfikatu ani użyć magazynu kluczy. Chcę móc wyjść na dowolne strony, określić, czy istnieje ważny certyfikat SSL, określić, czy nazwa hosta w certyfikacie jest zgodna z podaną nazwą i określić, kiedy wygaśnie ten certyfikat. Mam googleed ten temat, ale "Jak stworzyć klienta SSL przy użyciu Javy" nie przyniosło mi nic, a moje inne wyszukiwania tylko przyniosły mi linki, jak stworzyć samopodpisany certyfikat. Każda pomoc będzie bardzo ceniona.Pisanie sprawdzania SSL przy użyciu Javy

Odpowiedz

1

Co można zrobić, to zaimplementować własną sprawdzania na wierzchu np Apache's HttpClient
Należy zainicjować kontekstu SSL i zastąpić TrustManagers zrobić każdy sprawdzanie chcesz.

Weryfikacja nazwy hosta może być przeprowadzana automatycznie przez bibliotekę.

E.g. dodaje skonfiguruje obsługę gniazda SSL rzucić wyjątek, jeśli nazwa hosta nie pasuje info certyfikatu:

SSLSocketFactory sf = new SSLSocketFactory(
    SSLContext.getInstance("TLS"), 
    SSLSocketFactory.STRICT_HOSTNAME_VERIFIER); 
3

Aby uzyskać certyfikat serwera na pierwszym miejscu w tym celu sprawdzenia ręcznie, niezależnie od tego, czy jest to ważne lub nie, najłatwiej jest połączyć się przez SSLSocket po wyłączeniu jakiejkolwiek weryfikacji certyfikatu.

Załóż SSLContext który pozwala niczego przez:

SSLContext sslContext = SSLContext.getInstance("TLS"); 
X509TrustManager passthroughTrustManager = new X509TrustManager() { 
    @Override 
    public void checkClientTrusted(X509Certificate[] chain, 
      String authType) throws CertificateException { 
    } 

    @Override 
    public void checkServerTrusted(X509Certificate[] chain, 
      String authType) throws CertificateException { 
    } 

    @Override 
    public X509Certificate[] getAcceptedIssuers() { 
     return null; 
    } 
}; 
sslContext.init(null, new TrustManager[] { passthroughTrustManager }, 
     null); 

(marginesie: dla osób, które szukają sposobu, aby używać certyfikatów testowych wewnętrznie, polecam budowaniu własnego testu Kalifornia zamiast wyłączania kontroli, po prostu na wypadek, gdyby te fałszywe kontrole zostały przez pomyłkę pominięte w kodzie produkcyjnym, a także dlatego, że sprawiają, że testy są bardziej realistyczne.)

Utwórz gniazdo, podłącz i uruchom jawny uścisk dłoni (ponieważ tak naprawdę nie będziesz czytać formularza it):

SSLSocketFactory ssf = sslContext.getSocketFactory(); 
SSLSocket socket = (SSLSocket) ssf.createSocket(
     "the.host.name", 443); 
socket.startHandshake(); 

Uzyskaj sieć certyfikatów równorzędnych. Pierwszym elementem jest aktualny certyfikat serwera.

X509Certificate[] peerCertificates = (X509Certificate[]) socket 
     .getSession().getPeerCertificates(); 

Jeśli chcesz potwierdzić przed kotew domyślny powierniczych (domyślnie zaufane certyfikaty CA), zbudować X509TrustManager na podstawie wartości domyślnych (to skutecznie, co passthroughTrustManager powyżej wyłączone):

// By default on Oracle JRE, algorithm is PKIX 
TrustManagerFactory tmf = TrustManagerFactory 
     .getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
// 'null' will initialise the tmf with the default CA certs installed 
// with the JRE. 
tmf.init((KeyStore) null); 
X509TrustManager tm = (X509TrustManager) tmf.getTrustManagers()[0]; 

Sprawdź teraz, czy certyfikat jest aktualny w czasie, czy jest zweryfikowany względem zaufanej kotwicy i czy ma odpowiednie rozszerzenia zgodnie z RFC 3280.

try { 
    // Assuming RSA key here. 
    tm.checkServerTrusted(peerCertificates, "RSA"); 
} catch (CertificateException e) { 
    // Here you may check which subclass of CertificateException to know what the error is. 
} 

Wszystkie powyższe wykorzystuje JSSE API.

Alternatywnie, jeśli chcesz zagłębić się w szczegóły PKIX, możesz użyć opcji Java Certification Path API (która jest używana przez JSSE).

(Jeśli na początku potrzebujesz tylko ważnych certyfikatów, po prostu użyj SSLContext sslContext = SSLContext.getDefault() na początku, utwórz gniazdo i wykonaj uzgadnianie.)

Aby uzyskać certyfikat serwera bezpośrednio, można użyć to:

X509Certificate serverCert = peerCertificates[0]; 

X509Certificate posiada szereg metod dotyczących dat i różnych rozszerzeń. Np

Date expirationDate = serverCert.getNotAfter(); 

Weryfikacja hosta należy postępować RFC 6125 (lub co najmniej RFC 2818). W skrócie, sprawdź, czy nazwa hosta, z którą chcesz się połączyć, jest jedną z pozycji DNS usługi Subject Alternative Names (SAN). W przeciwnym razie sprawdź, czy nazwa hosta znajduje się w CN RDN twojego certyfikatu (w tym celu musisz podzielić nazwę wyróżniającą podmiot na RDN). Możesz być także zainteresowany this discussion (on the specific case of using IP addresses).

Wszystko zależy od tego, ile "ręcznej" weryfikacji chcesz wykonać. Istnieje wiele specyfikacji do odczytu (przynajmniej RFC 5280/RFC 3280 i RFC 6125/RFC 2818), oprócz dokumentacji API.

To pytanie na Security.SE powinna być także interesujące:

+0

uzyskać nonconvertible typy gdy próbuje to zrobić: X509Certificate [] peerCertificates = (X509Certificate [ ]) socket.getSession(). getPeerCertificates(); – W3B5T4R

+0

Próbowałem nawet przykładu z witryny Oracles, używając powyższego i nadal otrzymuję "typy niewspółmierne" – W3B5T4R

+0

Nieważne, widziałem, używałam import javax.security.cert.X509Certificate; zamiast importować java.security.cert.X509Certyfikat; – W3B5T4R

Powiązane problemy