2011-12-17 17 views
6

Qualcuno sa di buoni tutorial, siti e libri sulla scrittura di un correttore SSL in Java? Sto cercando di fare ciò che può essere trovato qui: http://www.sslshopper.com/ssl-checker.html. Non sto cercando di creare un certificato autofirmato o di utilizzare un keystore. Voglio essere in grado di accedere a qualsiasi sito per determinare se esiste un certificato SSL valido, determinare se il nome host sul Cert corrisponde al nome inserito e determinare quando questo Cert scadrà. Ho cercato su Google questo argomento ma "Come creare un acquirente SSL utilizzando Java" non mi ha dato alcun risultato e le mie altre ricerche mi hanno portato solo link su come creare un certificato autofirmato. Qualsiasi aiuto sarebbe molto apprezzato.Scrittura di un Checker SSL utilizzando Java

risposta

1

Che cosa si può fare è implementare la propria pedina in cima ad es Apache's HttpClient
Si dovrebbe inizializzare un contesto SSL e sovrascrivere il TrustManagers di fare qualsiasi controllo che si desidera.

La verifica del nome host può essere eseguita automaticamente dalla libreria.

E.g. il seguente sarà configurare la gestione presa SSL per un'eccezione se il nome host non corrisponde informazioni del certificato:

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

Per ottenere il certificato del server, in primo luogo, al fine di fare la verifica manualmente, indipendentemente dal fatto che sia valido o no, il più semplice è quello di connettersi tramite un SSLSocket dopo aver disabilitato qualsiasi verifica del certificato.

Crea un SSLContext che lascia qualsiasi cosa attraverso:

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); 

(Nota a margine: per persone in cerca di un modo per utilizzare i certificati di prova internamente, io consiglierei di costruire il proprio test di CA piuttosto che Disabilitazione dei controlli, basta nel caso in cui quei falsi assegni vengano lasciati nel codice di produzione per errore, e anche perché rende i test più realistici.)

Creare un socket, connettere e avviare l'handshake in modo esplicito (poiché non hai intenzione di leggere il modulo it):

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

Ottieni la catena di certificati peer. Il primo elemento è il certificato del server effettivo.

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

Se si desidera convalidare contro le ancore di default di fiducia (il default di fiducia certificati CA), costruire un X509TrustManager in base ai valori di default (questo è effettivamente ciò che il passthroughTrustManager sopra disabilitato):

// 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]; 

Ora, controlla se il certificato è attualmente valido nel tempo, se è verificato contro un ancoraggio attendibile e se ha le estensioni corrette in base a 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. 
} 

Tutto quanto sopra utilizza lo JSSE API.

In alternativa, se si desidera approfondire i dettagli di PKIX, è possibile utilizzare Java Certification Path API (che viene utilizzato da JSSE).

(Se si desidera comunque solo certificati validi per iniziare, è sufficiente utilizzare SSLContext sslContext = SSLContext.getDefault() all'inizio, creare il socket e fare l'handshake.)

Per ottenere direttamente il certificato del server, è possibile utilizzare questo:

X509Certificate serverCert = peerCertificates[0]; 

X509Certificate ha un certo numero di metodi per quanto riguarda date e varie estensioni. Ad esempio:

Date expirationDate = serverCert.getNotAfter(); 

La verifica host deve seguire RFC 6125 (o almeno RFC 2818). In breve, controllare se il nome host a cui si intendeva connettersi è una voce DNS di Subject Alternative Names (SAN). In caso contrario, tornare a controllare se il nome host è nel RDN CN del certificato (per questo, è necessario dividere il DN soggetto in RDN). Potresti anche essere interessato a this discussion (on the specific case of using IP addresses).

Tutto dipende dalla quantità di verifica "manuale" che si desidera effettuare. Ci sono un certo numero di specifiche da leggere (RFC 5280/RFC 3280 e RFC 6125/RFC 2818 almeno), oltre alle documentazioni API.

Questa domanda su Security.SE dovrebbe essere interessanti:

+0

ottengo tipi non convertibili quando si cerca di fare questo: X509Certificate [] = peerCertificates (X509Certificate [ ]) socket.getSession() getPeerCertificates().; – W3B5T4R

+0

Ho anche provato un esempio dal sito di Oracles utilizzando quanto sopra e continuo a ottenere i "tipi inconvertibili" – W3B5T4R

+0

Non importa, vedo che stavo usando import javax.security.cert.X509Certificate; invece di importare java.security.cert.X509Certificate; – W3B5T4R

Problemi correlati