Comment importer un certificat SSL auto-signé vers Volley sur Android 4.1+
-
21-12-2019 - |
Question
Je développe une application Android qui utilise Volée.Toutes les communications se font via HTTPS connexion.Parce que je le teste sur un environnement local, j'utilise des certificats auto-signés pour Tomcat.
Avant, je n'avais qu'Android 2.3 et 3.0 dispositifs.Maintenant, j'ai aussi 4.1 et 4.4.
Mon implémentation utilise cette approche : http://developer.android.com/training/articles/security-ssl.html (partie Autorité de certification inconnue) Sur les appareils équipés d’Android jusqu'à 4.1 ça marche parfaitement.SSLSocketFactory avec les certificats personnalisés est transmis à Volley :
Volley.newRequestQueue(getApplicationContext(), new HurlStack(null, socketFactory));
Mais que se passe-t-il sur Android 4.1+ ?Pourquoi ça ne marche pas ?J'ai essayé aussi avec NullX509TrustManager comme ça:
private static class NullX509TrustManager implements X509TrustManager {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType)
throws CertificateException {
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType)
throws CertificateException {
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
}
Mais cela ne fonctionne toujours pas...
La solution
Je l'ai résolu avec une solution mentionnée ici:
http://developer.android.com/training/articles/security-SSL.HTML
Problèmes communs avec la vérification du nom d'hôte
En ajoutant le vérificateur de nom d'hôte personnalisé qui retourne true pour mon nom d'hôte dans Volley Project et édition Hurlestack OpenConnection Méthode:
if ("https".equals(url.getProtocol()) && mSslSocketFactory != null) {
((HttpsURLConnection)connection).setSSLSocketFactory(mSslSocketFactory);
((HttpsURLConnection)connection).setHostnameVerifier(new CustomHostnameVerifier());
}
Autres conseils
Si vous avez déjà un fichier
Étape 1: Écrivez cette méthode à votre code.
public SSLSocketFactory getSocketFactory(Context context)
throws CertificateException, IOException, KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
// Load CAs from an InputStream (could be from a resource or ByteArrayInputStream or ...)
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream caInput = new BufferedInputStream(context.getResources().openRawResource(R.raw.myFile));
// I paste my myFile.crt in raw folder under res.
Certificate ca;
//noinspection TryFinallyCanBeTryWithResources
try {
ca = cf.generateCertificate(caInput);
System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
} finally {
caInput.close();
}
// Create a KeyStore containing our trusted CAs
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
// Create a TrustManager that trusts the CAs in our KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
// Create an SSLContext that uses our TrustManager
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tmf.getTrustManagers(), null);
return sslContext.getSocketFactory();
}
Étape 2: Ajoutez simplement cette ligne ci-dessous avant de faire une demande à l'aide de Volley.
HttpsURLConnection.setDefaultSSLSocketFactory(getSocketFactory(context));
Android Studio vous demandera de joindre cette ligne en essayant / attraper toutes les exceptions projetées par notre méthode.Alors laissez-le juste faire ça.
codage heureux!
La méthode la plus simple que j'ai trouvée est ajouter cette classe et l'exécuter à partir de onCreate
méthode
new NukeSSLCerts().nuke();
Cela fera une volée de confiance à tous les certificats SSL
Trust Tous les certificats SSL: - Vous pouvez contourner SSL si vous souhaitez tester sur le serveur de test. Mais n'utilisez pas ce code pour la production.
public static class NukeSSLCerts {
protected static final String TAG = "NukeSSLCerts";
public static void nuke() {
try {
TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
X509Certificate[] myTrustedAnchors = new X509Certificate[0];
return myTrustedAnchors;
}
@Override
public void checkClientTrusted(X509Certificate[] certs, String authType) {}
@Override
public void checkServerTrusted(X509Certificate[] certs, String authType) {}
}
};
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
});
} catch (Exception e) {
}
}
}
Veuillez appeler cette fonction dans Oncreate () Fonction dans Activité ou dans votre classe d'applications.
NukeSSLCerts.nuke();
Ceci peut être utilisé pour Volley dans Android. Plus réf. https://newfivefour.com/android-trust-all-sssl-certificats.HTML