2009-08-02 10 views
17

Sto provando a scrivere un client SSL che invia la posta usando l'API javax.mail. Il problema che sto avendo è che il server richiede di usare SSL, ma il server è anche configurato con un certificato SSL non standard. Le pagine Web che ho trovato dicono che devo installare il certificato nel trust store. Non voglio farlo (non ho i permessi necessari.)È possibile far sì che Java ignori il "trust store" e accetti il ​​certificato SSL che ottiene?

  1. C'è un modo per far sì che Java ignori semplicemente l'errore del certificato e lo accetti?
  2. In caso contrario, esiste un modo per fare in modo che il trust store sia locale per il mio programma e non installato per l'intera JVM?
+0

Giusto per chiarire, è possibile modificare il codice del server o solo il client? –

+0

Ignorare il passaggio di verifica del certificato è una cattiva idea. Non c'è quasi nessun punto che parla * segretamente * a qualcuno se non si è assicurato chi è in primo luogo. L'opzione 2 (un negozio di fiducia locale) è abbastanza facile da usare. – Bruno

+1

Ignorare la fase di verifica va bene in alcune circostanze --- ad esempio, se ci si trova su una rete isolata e SSL è l'unico servizio abilitato non a causa della politica, ma perché l'amministratore non sa come abilitare il servizio non SSL . – vy32

risposta

16

È necessario creare un falso TrustManager che accetta tutti i certificati e registrarlo come manager. Qualcosa del genere:

public class MyManager implements com.sun.net.ssl.X509TrustManager { 
    public boolean isClientTrusted(X509Certificate[] chain) { return true; } 
    public boolean isHostTrusted(X509Certificate[] chain) { return true; } 
    ... 
} 


com.sun.net.ssl.TrustManager[] managers = 
    new com.sun.net.ssl.TrustManager[] {new MyManager()}; 

com.sun.net.ssl.SSLContext.getInstance("SSL"). 
     .init(null, managers, new SecureRandom()); 
+6

Tutto questo dovrebbe essere fatto usando l'API pubblica JSSE piuttosto che modificare le classi 'com.sun. *' Nascoste. (Vedi risposta so_mv.) – Bruno

6

Prova questo (risposta alla domanda 2):

System.setProperty("javax.net.ssl.trustStore", "/path/to/truststore"); 

È inoltre possibile specificare questo come un ulteriore parametro di riga di comando:

java -Djavax.net.ssl.trustStore=/path/to/truststore <remaining arguments> 

su Fedora questo potrebbe essere l'ampia Java System trust store in /etc/pki/java/cacerts

+1

c'è un modo per specificare "attendibile tutto" come secondo argomento in questo come usare * etc? –

+0

@UmerHayat No. Devi codificare come nelle altre due risposte. –

21

Codice di lavoro (in jdk1.6.0_23) per # 1.

Importazioni

import javax.net.ssl.HttpsURLConnection; 
import javax.net.ssl.SSLContext; 
import javax.net.ssl.TrustManager; 
import javax.net.ssl.X509TrustManager; 
import java.security.cert.X509Certificate; 

L'attuale fiducia tutto il codice TrustManager.

TrustManager trm = new X509TrustManager() { 
    public X509Certificate[] getAcceptedIssuers() { 
     return null; 
    } 

    public void checkClientTrusted(X509Certificate[] certs, String authType) { 

    } 

    public void checkServerTrusted(X509Certificate[] certs, String authType) { 
    } 
}; 

SSLContext sc = SSLContext.getInstance("SSL"); 
sc.init(null, new TrustManager[] { trm }, null); 
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); 
+0

Grazie, per me ha funzionato alla grande. L'unico problema è che imposta globalmente le impostazioni per fidarsi di tutti i certificati .... Un approccio più sicuro potrebbe essere quello di trasferire l'URLConnection su un HttpsURLConnection e la chiamata setSSLSocketFactory su quello.Tuttavia questa è una GRANDE risposta, molti altri hanno detto che era impossibile bypassare il controllo di trust ed era necessario aggiungere un certificato o modificare alcune opzioni JVM – Cervo

+4

Questo potrebbe essere necessario anche nel caso in cui il nome host non corrisponda al certificato: HostnameVerifier nullVerifier = new HostnameVerifier() { @Override public boolean verificare (String nome host, sessione SSLSession) { return true; } }; HttpsURLConnection.setDefaultHostnameVerifier (nullVerifier); – seanf

1

Basta aggiungere -Dtrust_all_cert=true agli argomenti VM. Questo argomento dice a java di ignorare tutti i controlli dei certificati.

+0

È piuttosto spaventoso, ma sembra una buona risposta! Mi piacerebbe farlo in Java, però, e forse avrei un po 'più di controllo in futuro. – vy32

+6

Questo non è un argomento VM e non funzionerà in generale. –

-2

In CLI è possibile aggiungere l'argomento -noCertificationCheck a java per ignorare i controlli del certificato.

Problemi correlati