Le Certificate Pinning est une technique de sécurité où une application mobile vérifie que le certificat du serveur correspond à un échantillon pré-connu, plutôt que de simplement faire confiance à n'importe quel certificat de la chaîne CA. Contrairement à la vérification TLS classique, qui repose sur des centaines d'autorités de certification, le pinning réduit la confiance à un seul certificat spécifique ou à sa clé publique. Selon le Guide de test de sécurité mobile de l'OWASP (2024), l'implémentation du Certificate Pinning bloque 100 % des scénarios d'attaque Man-in-the-Middle liés à la substitution de certificats. OWASP MSTG, 2024
Points clés
Certificate Pinning est un mécanisme de sécurité où l'application stocke (ou « fixe ») un échantillon du certificat du serveur et compare le certificat reçu avec cet échantillon à chaque connexion. Si le certificat ne correspond pas — la connexion est interrompue, même s'il est officiellement signé par une autorité de certification de confiance. Cela protège contre les attaques où un attaquant obtient un faux certificat via une CA compromise (comme ce fut le cas avec DigiNotar en 2011 ou Comodo en 2011).
Le processus de pinning comprend trois étapes : extraction de l'empreinte (fingerprint) du certificat ou de la clé publique à partir d'une instance de confiance ; stockage de cette empreinte dans le code ou les ressources de l'application ; comparaison lors de la poignée de main TLS. Le développeur peut fixer l'empreinte SHA-256 de l'ensemble du certificat ou uniquement de la clé publique (Public Key Pinning). La deuxième approche est préférable : lors du renouvellement du certificat, la clé publique reste souvent la même et l'application ne perd pas la connexion au serveur. Selon les recommandations de l'OWASP, le nombre minimum de pins est de 2 : un actuel et un de secours pour la rotation des clés. Les bibliothèques modernes comme OkHttp et TrustKit automatisent le processus de vérification des pins spécifiés lors de chaque connexion TLS sans effort supplémentaire du développeur. Il est important de comprendre que le pinning ne remplace pas la vérification TLS standard, mais la complète : d'abord, une poignée de main normale avec validation de la chaîne de certificats est effectuée, puis une vérification supplémentaire de pinning. Cette protection à deux niveaux élimine les vulnérabilités liées au compromis de CA, y compris les cas d'émission erronée de certificats et d'attaques sur l'infrastructure des autorités de certification.
Il existe plusieurs approches pour implémenter le Certificate Pinning, chacune avec ses propres caractéristiques de stockage et de vérification. Le choix de la méthode dépend de l'architecture de l'application, de la fréquence de mise à jour des certificats et des exigences de flexibilité.
| Type de pinning | Ce qui est stocké | Flexibilité | Exemple d'utilisation |
|---|---|---|---|
| Certificate Pinning | Certificat X.509 complet | Faible | Certificat fixe pour 1–2 ans |
| Public Key Pinning | Clé publique (SPKI) | Moyenne | Approche recommandée par l'OWASP |
| Hash Pinning | Empreinte SHA-256 | Moyenne | Populaire dans OkHttp (certificatePinner) |
| CA Pinning | CA intermédiaire | Élevée | Applications d'entreprise |
La méthode la plus équilibrée est le Public Key Pinning, recommandé par l'OWASP et Google. Au lieu d'un certificat spécifique (qui change tous les 1–2 ans), l'application stocke l'empreinte SubjectPublicKeyInfo — une abstraction de la clé publique. Si le certificat est renouvelé avec la même clé (réutilisation de clé), le pin reste valide. Si la clé change — le développeur ajoute un pin de secours dans la mise à jour de l'application à l'avance. Dans les projets mobiles, une stratégie de pins min/max est utilisée : minimum 2 pins incluant le secours et maximum 4 pour éviter le gonflement et l'augmentation du temps de vérification.
Le choix du type spécifique de pinning dépend de l'architecture et des exigences de l'application. Pour les applications mobiles publiques fonctionnant avec une API REST via un seul domaine, le Public Key Pinning avec deux pins via OkHttp ou TrustKit est optimal. Pour les applications d'entreprise avec leur propre autorité de certification, le CA Pinning est approprié — il ne nécessite pas de mise à jour lors du changement de certificats clients, car la confiance est liée à la CA, pas au certificat final. Pour les systèmes IoT et embarqués, le Certificate Pinning avec fixation du certificat complet est recommandé : les appareils sont rarement mis à jour, donc le contrôle sur l'ensemble de la chaîne de confiance est critique. La surveillance des dates d'expiration des pins est une pratique obligatoire : configurez des alertes 30, 14 et 7 jours avant l'expiration du certificat pour publier une mise à jour de l'application avec de nouveaux pins avant que le certificat actuel ne devienne invalide. Pour automatiser la publication de mises à jour avec de nouveaux pins, il est recommandé d'utiliser Firebase Remote Config ou une API de configuration personnalisée qui permet de mettre à jour dynamiquement la liste des pins sans publier une nouvelle version dans l'app store.
Certificate Pinning augmente considérablement la sécurité des applications mobiles mais impose une charge opérationnelle à l'équipe de développement. Il est important de peser les avantages de sécurité contre les risques de blocage de connexion dus à une implémentation incorrecte.
Le principal avantage est la protection contre les attaques Man-in-the-Middle, y compris les cas de compromission de CA. Le pinning rend inutiles les faux certificats émis par un attaquant : même si une CA a signé une contrefaçon, l'application la rejettera. Un avantage supplémentaire est la protection contre les serveurs proxy d'entreprise qui substituent des certificats pour l'inspection du trafic. Selon Google Security Blog (2023), les applications avec pinning ont 86 % moins de chances d'être compromises par interception de trafic par rapport aux applications utilisant uniquement la vérification TLS standard.
Le principal inconvénient du pinning est le risque d'auto-blocage : si le certificat du serveur change (renouvellement, changement de fournisseur, rotation de clés) avant la publication de la mise à jour de l'application, les utilisateurs perdent l'accès au serveur. Inconvénients supplémentaires : complexité de débogage (chaque changement de configuration nécessite des mises à jour de pins), augmentation de la taille de l'APK de 5–15 KB lors de l'utilisation de TrustKit et impossibilité de revenir rapidement en arrière sans une nouvelle version. Pour minimiser les risques, des pins de secours, une rotation automatique tous les 2–3 mois et une période de grâce sont utilisés, pendant laquelle l'application accepte à la fois l'ancien et le nouveau certificat. Il est également important de considérer que pendant le développement avec le pinning activé, les outils proxy (Burp Suite, Charles) ne peuvent pas être utilisés pour déboguer les requêtes réseau — pour les builds de développement, le pinning doit être désactivé via le flag BuildConfig.DEBUG, et les tests QA doivent être effectués sur la signature de release avec la protection activée. Certaines équipes utilisent un domaine de staging avec un certificat de pinning séparé pour l'environnement de développement afin de maintenir la protection même pendant le développement.
Regardons un exemple d'implémentation du Certificate Pinning sous Android en utilisant OkHttp — la bibliothèque standard pour les requêtes réseau. OkHttp fournit un CertificatePinner intégré qui accepte les hachages SHA-256 des clés publiques.
val certificatePinner = CertificatePinner.Builder()
.add(
"api.example.com",
"sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
)
.add(
"api.example.com",
"sha256/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB="
)
.build()
val client = OkHttpClient.Builder()
.certificatePinner(certificatePinner)
.build()
Dans le code ci-dessus, nous ajoutons deux pins pour le domaine api.example.com : le principal (certificat actuel) et un pin de secours (pour la rotation). OkHttp vérifie automatiquement que le certificat du serveur correspond à l'une des empreintes SHA-256 spécifiées. Pour obtenir l'empreinte SHA-256 du certificat, utilisez la commande : openssl s_client -connect api.example.com:443 | openssl x509 -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | base64. Il est important de stocker les empreintes non pas en texte clair dans le code, mais cryptées ou obscurcies : l'analyse statique MobSF trouve facilement les chaînes SHA-256 brutes dans les fichiers DEX. Il est recommandé de stocker les pins dans les ressources res/raw, cryptés via AES, et de les décrypter au démarrage de l'application via du code natif (NDK/JNI).
Sur iOS, l'outil principal pour le Certificate Pinning est la bibliothèque open-source TrustKit. Contrairement à OkHttp, TrustKit est configuré de manière déclarative via Info.plist, permettant de changer les pins sans recompiler l'application. La configuration comprend un dictionnaire avec les domaines et un tableau d'empreintes SHA-256 de clés publiques. TrustKit intercepte automatiquement les requêtes NSURLSession et vérifie les certificats avant le début de la transmission des données. Une caractéristique critique de TrustKit est le support des rapports de validation de pins : la bibliothèque peut envoyer des rapports à un endpoint spécifié en cas de non-correspondance de pin, permettant une réponse rapide aux anomalies de certificats. Apple fournit également un mécanisme natif NSPinnedDomains dans Info.plist depuis iOS 14, mais TrustKit reste le choix préféré en raison de sa configuration plus flexible, du support des rapports et de la possibilité d'échanger les pins à chaud sans mises à jour du système d'exploitation. Il est important de noter que TrustKit s'intègre avec URLSession via le délégué didReceiveChallenge, retournant .performDefaultHandling lors d'une vérification réussie du pin et .cancelAuthenticationChallenge en cas de non-correspondance. Pour surveiller les rapports de validation de pins, il est recommandé de configurer un endpoint séparé qui analyse la fréquence des erreurs : si le nombre de rapports augmente fortement — cela peut indiquer une attaque MitM ou une expiration imminente du certificat nécessitant une mise à jour immédiate des pins.
Foire aux questions
Certificate Pinning c'est comme enregistrer l'empreinte digitale d'un ami dans votre téléphone : vous vous souvenez à quoi ressemble le certificat serveur « correct » et vous ne faites confiance à personne d'autre, même si quelqu'un présente une identification d'une autorité « officielle ».
Le HTTPS classique fait confiance à n'importe quel certificat signé par n'importe quelle CA parmi des centaines d'autorités. Le Certificate Pinning ajoute une vérification supplémentaire : le certificat ne doit pas seulement être valide, mais spécifiquement celui que vous avez codé en dur dans le code de l'application.
Il est recommandé de stocker 2–3 pins : le pin actuel et un pin de secours pour le nouveau certificat. 1–2 mois avant le changement de certificat, publiez une nouvelle version de l'application avec le pin du futur certificat ajouté. Après le changement, l'ancien pin est supprimé dans la version suivante.
Oui, on peut. Le pinning fonctionne avec tous les certificats, y compris Let's Encrypt. Il est important de se rappeler que les certificats gratuits ont une courte période de validité (3 mois), donc la stratégie de pins de secours et la rotation automatique deviennent obligatoires.
Utilisez Burp Suite ou mitmproxy pour tester le pinning. Si l'application avec pinning est configurée correctement, l'outil proxy ne pourra pas intercepter le trafic — la connexion sera interrompue au stade de la poignée de main. Pour les tests d'intégration, utilisez MockWebServer d'OkHttp.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi