Dans cet article, nous allons voir comment importer un certificat auto-signé dans votre application pour réaliser une connexion SSL sécurisée à l’aide de Bouncy Castle.
Android possède un Keystore contenant toutes les clés publiques certifiées par Google. Si vous tentez de faire une requête HTTPS depuis votre application sur un site ayant un certificat auto-signé, il y a de fortes chances qu’elle soit refusée. Voici comment ajouter un certificat auto-signé à votre application.
BouncyCastle Provider
Pour commencer, vous devez télécharger BouncyCastle Provider disponible ici (un fichier jar) et le placer dans un dossier que vous saurez retrouver ensuite.
Récupérer les certificats
Depuis un navigateur comme Chrome ou Firefox, rien de plus simple:
- depuis une page de votre site : clic droit/afficher les informations.
- Ensuite exportez le certificat au format .cer. Dans le cas où vous avez une chaine de certificat, toute la chaine est nécessaire.
Création du keystore
Ouvrez une fenêtre en ligne de commande. Il faut que vous vous trouviez dans le dossier …/Java/jre/bin pour pouvoir utiliser l’outil keytool. Pour cela, tapez “cd chemin_vers_java/Java/jre/bin”. Tapez ensuite la commande suivante:
keytool -importcert -v -trustcacerts -file "chemin_vers_le_certificat/moncertificat.cer" -alias IntermediateCA -keystore "chemin_nouveau_keystore/myKeystore.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "chemin_vers_bouncycastle/bcprov-jdk16-146.jar" -storetype BKS -storepass monmotdepasse
Un message doit normalement vous dire “Un certificat a été ajouté au keystore”
NOTE : si vous avez une chaine de certificats, commencez par le certificat le plus bas et remontez ensuite vers le certificat racine.
La commande suivante permet de vérifier que le certificat a été ajouté :
keytool -list -keystore " chemin_nouveau_keystore/myKeystore.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath " chemin_vers_bouncycastle /bcprov-jdk16-145.jar" -storetype BKS -storepass monmotdepasse
NOTE : le mot de passe (storepass) servira lors de chaque ouverture de notre keystore.
Si le certificat a été ajouté, vous aurez un message de ce genre:
IntermediateCA, 22.10.2010, trustedCertEntry, Thumbprint (MD5): 98:0F:C3:F8:39:F7:D8:05:07:02:0D:E3:14:5B:29:43
Vous devez ensuite ajouter le keystore créé dans les ressources du projet, dans le dossier res/raw.
Création d’une classe HTTP personnalisée
Créez ensuite une nouvelle classe nommée “MyHttpClient“. Cette classe dérivera de la classe DefaultHttpClient définie par Android et utilisera le keystore créé précédemment.
public class MyHttpClient extends DefaultHttpClient {
final Context context;
public MyHttpClient(Context context) {
this.context = context;
}
@Override
protected ClientConnectionManager createClientConnectionManager() {
SchemeRegistry registry = new SchemeRegistry();
//Pour les requêtes HTTP, on laisse la classe de base s'en occuper.
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
// Les requêtes HTTPS se font sur le port 443. A chaque connexion HTTPS, c’est notre keystore qui sera utilisé.
registry.register(new Scheme("https", newSslSocketFactory(), 443));
return new SingleClientConnManager(getParams(), registry);
}
private SSLSocketFactory newSslSocketFactory() {
try {
// On obtient une instance de notre KeyStore
trusted = KeyStore.getInstance("BKS");
InputStream in = context.getResources().openRawResource(R.raw.mykeystore);
try {
// Initialisation de notre keystore. On entre le mot de passe (storepass)
trusted.load(in, "monmotdepasse".toCharArray());
} finally {
in.close();
}
// Passons le keystore au SSLSocketFactory qui est responsable de la verification du certificat
SSLSocketFactory sf = new SSLSocketFactory(trusted);
sf.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);
return sf;
} catch (Exception e) {
throw new AssertionError(e);
}
}
}
On utilise ensuite cette classe comme la classe HTTP de base d’Android:
DefaultHttpClient client = new MyHttpClient(getApplicationContext()); HttpGet get = new HttpGet("https://monsitesecurise.com");
Conclusion
Voilà le tutoriel est terminé, en espérant que vous ayez compris comment ajouter vos propres certificats.



Merci infiniment pour ce tuto.
avec Android,une fois on a l’apk de l’application, on peut extraire toutes les ressources y compris le certificat et puis, on peut aussi avoir le code source de l’application et donc avoir le mot de passe du certificat.
alors toute personne peut avoir le certificat et son mot de passe et pourra donc créer facilement une autre application qui communique avec le serveur!!
ceci pose un grand problème de sécurité n’est ce pas ?!!
Effectivement c’est possible. Malheureusement c’est le gros problème avec Android et il est difficile de sécuriser davantage
Merci Arnaud pour ta réponse.
je te serai reconnaissant si tu peux m’indiquer d’autres moyens pour sécuriser davantage une application android surtout les échanges entre un client mobile et un serveur web.
peu importe si c’est difficile, l’essentiel que ça soit pas impossible.
Bonjour,
j’ai un problème dans mon application android ,l’erreur est “No peer certificate”
Pouvez vous m’explique cette erreur?
Cela signifie que le certificat n’est pas trouvé lors de la requête. Il a dû être mal ajouté au keystore.
Bonjour,
j’ai effectué toute les manoeuvres indiquées et bien récupéré les 3 certificats pour le site ” https://www.mobileresto.com/ ” je les ai ajoutés au keystore mais lorsque j’execute ma commande il me met malgré tout no peer certificate.
Auriez vous une idée?
Merci pour vos réponses
Essaie avec cette librairie. Elle utilise une autre classe pour les requêtes, ça fonctionnera peut-être mieux. Désolé pour la réponse tardive, je n’ai pas trop de temps en ce moment.
http://code.google.com/p/simplehttpsandroid/downloads/list
Merci pour ta réponse
entre temps j’ai eu l’ocassion de trouver une solution. J’ai donc posté une librairie sur github qui permet d’effectuer des requêtes https à l’aide de doPost ou doGet.
avec l’url c’est mieux :p
https://github.com/raphcho/HttpsLib
J’ai comme l’impression que cette librairie ne fait qu’accepter tous les certificats, sans rien vérifier. Le problème est que tu perds tout l’aspect sécurité d’une connexion HTTPS vu que tous les certificats sont validés.
Salut , ce code marche pas avec moi , je pense que la classe SSLSocketFactory est absraite du coup cette ligne ” SSLSocketFactory sf = new SSLSocketFactory(trusted); ”
est une erreur ! merci de votre aide
L’erreur vient certainement d’un mauvais import. Ici, l’import doit être import org.apache.http.conn.ssl.SSLSocketFactory;
Tu as sûrement importé le mauvais package (javax.net.ssl.SSLSocketFactory)
merci beaucoup
very useful cet tuto