Ho cercato per giorni di farlo funzionare. Sto cercando di connettermi al mio server su https con un certificato autofirmato. Non penso che ci siano pagine o esempi che non ho ancora letto.OkHttp javax.net.ssl.SSLPeerUnverifiedException: hostname domain.com non verificato
quello che ho fatto:
- Creato BKS chiavi seguendo questo tutorial: http://blog.crazybob.org/2010/02/android-trusting-ssl-certificates.html
utilizza openssl s_client -connect domain.com:443
per ottenere il certificato dal server. Quindi crea un keystore bks usando il castello rimbalzante.
Leggere il keystore creato dalla cartella raw aggiungendolo a sslfactory e quindi a OkHttpClient. Come questo:
public ApiService() { mClient = new OkHttpClient(); mClient.setConnectTimeout(TIMEOUT_SECONDS, TimeUnit.SECONDS); mClient.setReadTimeout(TIMEOUT_SECONDS, TimeUnit.SECONDS); mClient.setCache(getCache()); mClient.setCertificatePinner(getPinnedCerts()); mClient.setSslSocketFactory(getSSL()); } protected SSLSocketFactory getSSL() { try { KeyStore trusted = KeyStore.getInstance("BKS"); InputStream in = Beadict.getAppContext().getResources().openRawResource(R.raw.mytruststore); trusted.load(in, "pwd".toCharArray()); SSLContext sslContext = SSLContext.getInstance("TLS"); TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); trustManagerFactory.init(trusted); sslContext.init(null, trustManagerFactory.getTrustManagers(), null); return sslContext.getSocketFactory(); } catch(Exception e) { e.printStackTrace(); } return null; } public CertificatePinner getPinnedCerts() { return new CertificatePinner.Builder() .add("domain.com", "sha1/theSha=") .build(); }
Questo per qualche motivo questo genera sempre un
SSLPeerUnverifiedException
con o senza chiavi. E con o senza ilCertificatePinner
.javax.net.ssl.SSLPeerUnverifiedException: Hostname domain.com not verified: 0 W/System.err﹕ certificate: sha1/theSha= W/System.err﹕ DN: 1.2.840.113549.1.9.1=#1610696e666f40626561646963742e636f6d,CN=http://domain.com,OU=development,O=domain,L=Valencia,ST=Valencia,C=ES W/System.err﹕ subjectAltNames: [] W/System.err﹕ at com.squareup.okhttp.internal.http.SocketConnector.connectTls(SocketConnector.java:124) W/System.err﹕ at com.squareup.okhttp.Connection.connect(Connection.java:143) W/System.err﹕ at com.squareup.okhttp.Connection.connectAndSetOwner(Connection.java:185) W/System.err﹕ at com.squareup.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:128) W/System.err﹕ at com.squareup.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:341) W/System.err﹕ at com.squareup.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:330) W/System.err﹕ at com.squareup.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:248) W/System.err﹕ at com.squareup.okhttp.Call.getResponse(Call.java:273) W/System.err﹕ at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:230) W/System.err﹕ at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:201) W/System.err﹕ at com.squareup.okhttp.Call.execute(Call.java:81) ...
Che cosa sto facendo di sbagliato?
Verificare che il certificato contenga il nome host effettivo e non l'indirizzo IP (gli indirizzi IP devono essere nel campo "Nome alternativo soggetto" del certificato). Per quanto riguarda 'HostnameVerifier' che restituisce true - renderà SSL inutile e insicuro (la risposta più upvoted). Su Android androidi è possibile installare il certificato autofirmato senza problemi tramite le impostazioni di sicurezza. –