Les étapes principales suivantes sont nécessaires pour établir une connexion sécurisée à partir des autorités de certification qui ne sont pas considérées comme fiables par la plateforme Android.
Comme demandé par de nombreux utilisateurs, j'ai reflété les parties les plus importantes de mon article de blog ici :
- Saisissez tous les certificats nécessaires (racine et tout certificat intermédiaire CA)
- Créez un keystore avec keytool et le fournisseur BouncyCastle et importez les certificats
- Chargez le keystore dans votre application Android et utilisez-le pour les connexions sécurisées (je recommande d'utiliser le Apache HttpClient au lieu du standard
java.net.ssl.HttpsURLConnection
(plus facile à comprendre, plus performant)
Saisir les certificats
Vous devez obtenir tous les certificats qui constituent une chaîne depuis le certificat de point de terminaison jusqu'à la CA racine. Cela signifie, tout certificat intermédiaire CA (s'ils existent) et aussi le certificat de la CA racine. Vous n'avez pas besoin d'obtenir le certificat de point de terminaison.
Créer le keystore
Téléchargez le fournisseur BouncyCastle et stockez-le dans un emplacement connu. Assurez-vous également que vous pouvez invoquer la commande keytool (généralement située sous le dossier bin de votre installation de JRE).
Importez maintenant les certificats obtenus (ne importez pas le certificat de point de terminaison) dans un keystore formaté BouncyCastle.
Je ne l'ai pas testé, mais je pense que l'ordre d'importation des certificats est important. Cela signifie, importez d'abord le certificat de l'intermédiaire CA le plus bas, puis remontez jusqu'au certificat de la CA racine.
Avec la commande suivante, un nouveau keystore (si ce n'est pas déjà le cas) avec le mot de passe mysecret sera créé et le certificat de l'intermédiaire CA sera importé. J'ai également défini le fournisseur BouncyCastle, où il peut être trouvé sur mon système de fichiers et le format du keystore. Exécutez cette commande pour chaque certificat de la chaîne.
keytool -importcert -v -trustcacerts -file "path_to_cert/interm_ca.cer" -alias IntermediateCA -keystore "res/raw/mykeystore.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "path_to_bouncycastle/bcprov-jdk16-145.jar" -storetype BKS -storepass mysecret
Vérifiez si les certificats ont été importés correctement dans le keystore :
keytool -list -keystore "res/raw/mykeystore.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "path_to_bouncycastle/bcprov-jdk16-145.jar" -storetype BKS -storepass mysecret
Devrait afficher toute la chaîne :
RootCA, 22.10.2010, trustedCertEntry, Thumbprint (MD5): 24:77:D9:A8:91:D1:3B:FA:88:2D:C2:FF:F8:CD:33:93
IntermediateCA, 22.10.2010, trustedCertEntry, Thumbprint (MD5): 98:0F:C3:F8:39:F7:D8:05:07:02:0D:E3:14:5B:29:43
Maintenant vous pouvez copier le keystore en tant que ressource brute dans votre application Android sous res/raw/
Utiliser le keystore dans votre application
Tout d'abord, nous devons créer un HttpClient Apache personnalisé qui utilise notre keystore pour les connexions HTTPS :
import org.apache.http.*
public class MyHttpClient extends DefaultHttpClient {
final Context context;
public MyHttpClient(Context context) {
this.context = context;
}
@Override
protected ClientConnectionManager createClientConnectionManager() {
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
// Enregistrer pour le port 443 notre SSLSocketFactory avec notre keystore
// au ConnectionManager
registry.register(new Scheme("https", newSslSocketFactory(), 443));
return new SingleClientConnManager(getParams(), registry);
}
private SSLSocketFactory newSslSocketFactory() {
try {
// Obtenir une instance du format Bouncy Castle KeyStore
KeyStore trusted = KeyStore.getInstance("BKS");
// Obtenez la ressource brute, qui contient le keystore avec
// vos certificats de confiance (certificats root et intermédiaires)
InputStream in = context.getResources().openRawResource(R.raw.mykeystore);
try {
// Initialiser le keystore avec les certificats de confiance fournis
// Fournir également le mot de passe du keystore
trusted.load(in, "mysecret".toCharArray());
} finally {
in.close();
}
// Passez le keystore au SSLSocketFactory. L'usine est responsable
// de la vérification du certificat du serveur.
SSLSocketFactory sf = new SSLSocketFactory(trusted);
// Vérification du nom d'hôte à partir du certificat
// http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d4e506
sf.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);
return sf;
} catch (Exception e) {
throw new AssertionError(e);
}
}
}
Nous avons créé notre HttpClient personnalisé, maintenant nous pouvons l'utiliser pour des connexions sécurisées. Par exemple lorsque nous effectuons un appel GET à une ressource REST :
// Instancier le HttpClient personnalisé
DefaultHttpClient client = new MyHttpClient(getApplicationContext());
HttpGet get = new HttpGet("https://www.mydomain.ch/rest/contacts/23");
// Exécuter l'appel GET et obtenir la réponse
HttpResponse getResponse = client.execute(get);
HttpEntity responseEntity = getResponse.getEntity();
C'est tout ;)
0 votes
Cette solution acceptée a fonctionné pour moi- stackoverflow.com/questions/2642777/…