Aller au contenu

Valider un certificat serveur sur mobile et embarqué

Valider un certificat serveur sur mobile et embarqué

Section intitulée « Valider un certificat serveur sur mobile et embarqué »

Transport Layer Security (TLS) ne protège un client mobile ou embarqué que si ce client refuse réellement les serveurs non autorisés. Accepter tout certificat pour accélérer un test transforme le chiffrement en décoration cryptographique, puis le raccourci finit souvent dans une version distribuée.

→ Lire l’explication complète de la marmotte

La validation standard d’un certificat serveur comporte trois contrôles indépendants. Le client doit construire une chaîne de certification vers une autorité de confiance, vérifier que le nom demandé apparaît dans l’extension subjectAltName, puis vérifier les dates de validité et les contraintes d’usage. Une signature cryptographique correcte ne compense jamais un nom incorrect. Un certificat pour api.example.net ne légitime pas api.example.com, même si les deux finissent dans le même diagramme d’architecture pastel.

La Public Key Infrastructure (PKI) fournit les autorités de certification racines et intermédiaires auxquelles le système fait confiance. Sur Android et iOS, les magasins de confiance sont maintenus par l’éditeur de la plateforme. Sur un système embarqué, ils sont souvent figés dans l’image logicielle. Ce dernier cas exige un inventaire explicite des racines embarquées, de leurs dates d’expiration et de la procédure de mise à jour du firmware.

Le nom vérifié doit être le nom logique du service, issu de l’URL ou de la configuration de l’application. Il ne doit jamais provenir d’une redirection, d’un en-tête reçu du réseau ou d’une adresse IP obtenue avant la négociation. Le Domain Name System (DNS) résout un nom vers une adresse, mais TLS valide le nom attendu contre le certificat. Confondre les deux fait croire qu’une adresse réseau est une identité. Ce n’est pas le cas, même avec un très beau pare-feu.

Le compromis central est net : s’appuyer sur le magasin de confiance de la plateforme apporte compatibilité, renouvellement souple et tolérance aux changements de certification, mais élargit l’ensemble des autorités capables de faire émettre un certificat accepté. Le pinning réduit cet ensemble et limite certaines émissions frauduleuses, mais rend la rotation de certificat et la reprise après incident plus coûteuses. La recommandation est de conserver la validation standard partout, puis de pinner uniquement les services dont l’identité serveur est sous contrôle direct et dont la rotation est industrialisée.

Les principes de chaîne et de nommage sont détaillés dans la PKI expliquée et dans le fonctionnement de TLS. Ici, le point critique est côté client : une infrastructure parfaite ne sauve pas une application qui appelle une fonction de confiance permissive.

Désactivation de la vérification : les échecs qui arrivent en production

Section intitulée « Désactivation de la vérification : les échecs qui arrivent en production »

Les contournements les plus dangereux portent des noms rassurants : TrustAll, AllowAnyHostname, InsecureSkipVerify, verify=false, ou un délégué de validation qui retourne systématiquement vrai. Ils apparaissent pour tester un environnement avec certificat auto-signé, intercepter un flux avec un proxy de débogage, ou contourner une erreur de chaîne incomplète. Le code compile, les tests passent, le risque reste. C’est précisément le genre de défaut qui attend tranquillement derrière une fonctionnalité parfaitement démontrable.

Un client qui accepte n’importe quel certificat est vulnérable à l’attaque de l’homme du milieu. Un attaquant capable de contrôler le réseau local, un point d’accès sans fil, un proxy d’entreprise compromis ou une résolution DNS peut présenter son propre certificat et déchiffrer la session. TLS continue à chiffrer, mais avec l’attaquant. La confidentialité devient alors une suggestion.

La désactivation conditionnelle est moins visible, pas moins mauvaise. Un test fondé sur un booléen debug, une saveur applicative, un nom d’hôte contenant dev, ou une variable d’environnement peut être activé par erreur dans un paquet de production. Une condition basée sur une constante compilée est préférable à une condition modifiable à l’exécution, mais ne résout pas le problème de gouvernance : le binaire de diffusion ne doit contenir aucun chemin d’exécution qui désactive la validation.

Sur Android, les ancres de confiance définies pour le débogage doivent être limitées au profil de débogage et exclues du manifeste de diffusion. Autoriser les certificats installés par l’utilisateur dans la configuration générale agrandit la surface d’attaque, notamment sur un terminal administré ou compromis. Sur iOS, un gestionnaire de défi TLS personnalisé ne doit pas accepter aveuglément une authentification serveur sous prétexte que le certificat de test est pénible.

Sur un équipement embarqué, l’erreur classique consiste à ignorer l’heure parce qu’aucune horloge fiable n’est disponible au démarrage. Il faut alors obtenir une heure authentifiée avant les connexions sensibles, conserver une horloge matérielle avec batterie, ou définir une phase d’amorçage strictement bornée. Ignorer durablement les dates revient à accepter des certificats expirés et augmente la fenêtre d’exploitation d’une clé compromise.

Le pinning associe le client à une information cryptographique attendue. Épingler le certificat entier lie le client à son renouvellement exact : chaque réémission impose une mise à jour applicative. Épingler la clé publique du sujet, souvent appelée Subject Public Key Info (SPKI), autorise le renouvellement du certificat avec la même clé. Cette souplesse a un prix : conserver la même clé plus longtemps augmente l’impact d’une compromission.

Le pinning de la SPKI est le meilleur choix lorsque le serveur est maîtrisé, que l’application communique avec un petit nombre de domaines stables et qu’une seconde clé de secours peut être distribuée avant besoin. Au moins deux pins doivent être présents : la clé active et une clé de rotation. Un seul pin transforme une perte de clé ou un renouvellement mal orchestré en panne totale jusqu’à la mise à jour des clients. Les objets connectés hors ligne apprécient peu cette démonstration de pureté cryptographique.

Le pinning ne remplace pas la validation standard. Il doit s’ajouter à la validation de chaîne, de nom, de date et d’usage. Accepter un certificat seulement parce que sa clé correspond à un pin, sans valider le nom, ouvre des erreurs de routage et des usages non prévus. À l’inverse, pinner une autorité intermédiaire est généralement trop large : toute émission par cette autorité pour un autre nom peut devenir acceptable selon l’implémentation.

Le pinning ne protège pas contre une application modifiée sur un terminal déverrouillé, contre l’extraction d’un jeton déjà obtenu, contre une compromission du serveur légitime ou contre un certificat valide émis par une autorité de confiance lorsque aucun pin ne s’applique. Il ne remplace ni l’authentification applicative, ni l’autorisation, ni la détection de fraude. Pour l’authentification du client par certificat, voir TLS mutuel.

Exemple Android : pins de clé publique et séparation débogage

Section intitulée « Exemple Android : pins de clé publique et séparation débogage »

La configuration suivante impose HTTPS, conserve les ancres système pour la production et ajoute deux pins SPKI pour api.example.net. Les empreintes se calculent sur la clé publique encodée, pas sur le certificat entier.

Fenêtre de terminal
# Extraire le pin SPKI SHA-256 depuis le certificat actuellement servi.
# Exécuter depuis une station disposant d'OpenSSL.
openssl s_client -connect api.example.net:443 -servername api.example.net </dev/null 2>/dev/null \
| openssl x509 -pubkey -noout \
| openssl pkey -pubin -outform der \
| openssl dgst -sha256 -binary \
| openssl base64
res/xml/network_security_config.xml
<network-security-config>
<base-config cleartextTrafficPermitted="false">
<trust-anchors>
<!-- Les ancres système restent la base de validation. -->
<certificates src="system" />
</trust-anchors>
</base-config>
<domain-config>
<domain includeSubdomains="false">api.example.net</domain>
<!-- La date d'expiration force une revue avant que le pin ne vieillisse seul. -->
<pin-set expiration="2027-06-01">
<pin digest="SHA-256">PIN_DE_LA_CLE_ACTIVE_EN_BASE64</pin>
<pin digest="SHA-256">PIN_DE_LA_CLE_DE_SECOURS_EN_BASE64</pin>
</pin-set>
</domain-config>
<debug-overrides>
<!-- Acceptable uniquement dans un paquet signé pour le débogage. -->
<trust-anchors>
<certificates src="user" />
</trust-anchors>
</debug-overrides>
</network-security-config>

Le manifeste de production doit référencer cette configuration sans mécanisme alternatif. Le pipeline de Continuous Integration and Continuous Delivery (CI/CD) doit analyser le paquet final, vérifier l’absence de bibliothèques qui installent un gestionnaire permissif, puis lancer un test négatif : présenter un certificat auto-signé, un certificat pour un autre nom et un certificat expiré doit faire échouer la connexion.

Les applications utilisant une bibliothèque HTTP tierce doivent vérifier son comportement réel. Certaines couches exposent un client TLS distinct pour les téléchargements, les websockets ou les mises à jour internes. Auditer seulement le client principal revient à vérifier la serrure et oublier la trappe de livraison.

Exploitation : rotation, révocation et supervision

Section intitulée « Exploitation : rotation, révocation et supervision »

La rotation commence avant l’émission du nouveau certificat. Une nouvelle clé publique doit être générée, ajoutée comme pin de secours dans une version applicative distribuée, puis activée côté serveur seulement lorsque la population de clients compatible atteint le seuil fixé par l’architecture. Pour les équipements rarement connectés, le pinning strict peut être inacceptable sans canal de mise à jour fiable et sans période de recouvrement longue.

La révocation d’un certificat ne se propage pas aux sessions déjà établies. De plus, les clients mobiles et embarqués ne consultent pas tous les mécanismes de statut en ligne de manière uniforme, notamment hors connexion. La réponse opérationnelle à une compromission est donc la rotation de clé et de certificat, la réduction de durée de vie des certificats, l’invalidation des jetons applicatifs exposés et, si nécessaire, une mise à jour du client. Compter sur une révocation distante comme sur un bouton rouge universel relève davantage du folklore que de l’architecture.

La supervision doit distinguer les échecs de chaîne, de nom, de date, de pin et de négociation TLS. Journaliser le code d’erreur, le nom cible, la version applicative et l’empreinte du certificat présenté permet de détecter une expiration imminente, une chaîne serveur incomplète ou une interception réseau. Ne pas journaliser de jetons d’accès, de données métier ou de secrets de session : un journal n’est pas un coffre-fort qui aurait appris à écrire.

Les secrets de signature des paquets mobiles, les clés des certificats serveurs et les clés de mise à jour firmware doivent rester séparés. Une même clé utilisée pour signer le logiciel et servir TLS fusionne deux périmètres de compromission qui n’ont aucune raison de se connaître. La sauvegarde doit couvrir les clés de secours, les configurations de pinning et les procédures de rotation, avec restauration testée. Sans test de restauration, une sauvegarde est une opinion.

Sans validation réelle du certificat serveur côté client, TLS ne protège plus rien sur mobile ou embarqué : le chiffrement subsiste, mais l’application ne vérifie plus à qui elle parle. Un intermédiaire placé sur le trajet présente alors son propre certificat, la connexion s’établit sans broncher, et il lit ou modifie tout ce qui transite tout en paraissant chiffré. Accepter n’importe quel certificat pour accélérer un test revient à retirer le contrôle d’identité du visiteur à l’entrée : la porte reste verrouillée mais s’ouvre à quiconque se présente. La conséquence la plus fréquente est que ce raccourci de développement se retrouve dans une version distribuée, exposant durablement les identifiants, jetons et données échangés par l’application. Sans ce refus effectif des serveurs non autorisés, le chiffrement devient une décoration cryptographique qui rassure sans protéger.

Quand une application contacte un serveur, elle commence par demander une connexion chiffrée. Le serveur envoie un document électronique appelé certificat. Ce document contient son nom, une clé publique et une signature produite par une autorité reconnue par le téléphone ou l’équipement.

L’application doit vérifier plusieurs choses avant d’envoyer des données. Elle vérifie que la signature remonte à une autorité autorisée, que le nom présent dans le document correspond exactement au nom du serveur demandé et que les dates sont encore valides. Si un contrôle échoue, la connexion doit s’arrêter. Continuer malgré l’erreur permettrait à un intermédiaire sur le réseau de se faire passer pour le serveur.

Certaines applications ajoutent une vérification supplémentaire appelée pinning. Elles enregistrent à l’avance une empreinte de la clé publique attendue du serveur. Lors de la connexion, la clé reçue doit correspondre à une des empreintes enregistrées. Deux empreintes sont nécessaires : une pour la clé actuelle et une pour une future clé, afin de pouvoir remplacer la première sans bloquer les anciennes applications.

En développement, un certificat temporaire peut provoquer des erreurs. Désactiver les contrôles pour les faire disparaître est dangereux si ce réglage atteint la version distribuée. Les tests doivent donc vérifier qu’un faux certificat, un mauvais nom et un document expiré sont tous refusés.

À lire aussi

Pages voisines

: les deux pages se citent l’une l’autre.