Bouclier de sécurité mobile (OtaSecurityShield)
Le module lib/src/security/ota_security_shield.dart protège l'application mobile contre trois vecteurs d'attaque majeurs avant tout appel réseau ou application de patch OTA :
- L'Anti-Repackaging APK (vérification de l'empreinte SHA-256 du certificat de signature de l'APK).
- La détection d'appareils compromis (Root sur Android et Jailbreak sur iOS).
- Le Certificate Pinning TLS SHA-256 (validation des octets DER du certificat X.509 du serveur OTA).
1. Configuration de la politique (OtaSecurityPolicy)
La politique de sécurité est définie via la classe OtaSecurityPolicy et passée à TkOtaPush.init(...) :
final ota = TkOtaPush.init(
appReleaseVersion: '1.0.0+3',
securityPolicy: const OtaSecurityPolicy(
// 1. Empreintes SHA-256 autorisées du certificat de signature APK
expectedApkSignaturesSha256: {
'A1:B2:C3:D4:E5:F6:01:02:03:04:05:06:07:08:09:10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26',
},
// 2. Blocage des appareils Rootés / Jailbreakés
blockRootedOrJailbrokenDevices: true,
// 3. Empreintes SHA-256 des certificats TLS serveur (X.509 DER)
pinnedServerCertSha256Fingerprints: {
'42d889f8f4b6bf9d3abb767d3b5f215e0009e4d26cb7b958497e8b291e1b96dc',
},
),
onSecurityViolation: (OtaSecurityVerdict verdict) async {
debugPrint('Violation détectée (${verdict.violationType}) : ${verdict.reason}');
},
);
Normalisation des empreintes SHA-256
La méthode utilitaire OtaSecurityPolicy.normalizeSha256(String fingerprint) supprime automatiquement les deux-points (:), les tirets (-) et les espaces, puis convertit la chaîne en minuscules :
'A1:B2:C3...'et'a1b2c3...'sont traités de façon strictement équivalente.
2. Anti-Repackaging APK vs Partage hors-ligne (Xender / ShareIt)
Sur de nombreux marchés, les utilisateurs partagent le fichier .apk d'une application entre smartphones via des outils pair-à-pair hors-ligne (Xender, ShareIt, Bluetooth).
- APK officiel partagé via Xender : le fichier APK n'a pas été modifié ; son certificat de signature cryptographique reste celui du keystore officiel de l'éditeur.
evaluatePolicyvalide l'empreinte et autorise à 100 % les mises à jour OTA. - APK pirate décompilé et re-signé : un attaquant qui modifie le bytecode ou les ressources de l'APK doit obligatoirement le re-signer avec sa propre clé privée. L'empreinte SHA-256 observée diverge alors de
expectedApkSignaturesSha256: le SDK bloque immédiatement toute opération OTA avecOtaSecurityViolationType.apkSignatureMismatch.
Fournir la signature APK native à DefaultOtaDeviceIntegrityInspector
Par défaut, DefaultOtaDeviceIntegrityInspector.readInstalledApkSignatureSha256() :
- Appelle le callback
apkSignatureProviders'il a été fourni au constructeur. - Sinon, lit la variable d'environnement
Platform.environment['OTA_APK_SIGNATURE_SHA256'].
Pour brancher la lecture native Android (PackageManager.GET_SIGNING_CERTIFICATES via un MethodChannel) :
const platformChannel = MethodChannel('com.monapp/security');
final inspector = DefaultOtaDeviceIntegrityInspector(
apkSignatureProvider: () async {
return await platformChannel.invokeMethod<String>('getApkSignatureSha256');
},
);
final ota = TkOtaPush.init(
appReleaseVersion: '1.0.0+3',
deviceIntegrityInspector: inspector,
securityPolicy: const OtaSecurityPolicy(
expectedApkSignaturesSha256: {'6b6929c8ff345cf008496328d7bff081a8ccfb89498bf9916ed668be3c3dedcf'},
),
);
3. Détection Root (Android) et Jailbreak (iOS)
Lorsque blockRootedOrJailbrokenDevices: true, DefaultOtaDeviceIntegrityInspector.isDeviceRootedOrJailbroken() vérifie sur Android et iOS (Platform.isAndroid || Platform.isIOS) la présence sur le système de fichiers des chemins compromis suivants :
| Plateforme | Chemins inspectés par défaut (_defaultSuspiciousPaths) |
|---|---|
| Android (Root) | /system/app/Superuser.apk, /sbin/su, /system/bin/su, /system/xbin/su, /data/local/xbin/su, /data/local/bin/su, /system/sd/xbin/su, /sbin/magisk |
| iOS (Jailbreak) | /Applications/Cydia.app, /Library/MobileSubstrate/MobileSubstrate.dylib, /private/var/lib/apt, /private/var/stash |
Vous pouvez également injecter votre propre liste de chemins via le paramètre customSuspiciousPaths de DefaultOtaDeviceIntegrityInspector, ou implémenter directement la classe abstraite OtaDeviceIntegrityInspector.
4. Certificate Pinning TLS SHA-256 (OtaCertificatePinner & OtaPinnedHttpOverrides)
Pour protéger les téléchargements d'assets et les appels HTTPS Dart contre les attaques Man-in-the-Middle (MitM) par certificat racine frauduleux, le SDK fournit OtaCertificatePinner et OtaPinnedHttpOverrides.
Fonctionnement de OtaCertificatePinner
OtaCertificatePinner.computeDerSha256Hex(List<int> derBytes)calcule le condensat SHA-256 hexadécimal (en minuscules) des octets DER bruts (cert.der) du certificat X.509 présenté par le serveur.- Si
pinnedSha256Fingerprintsest vide,verifyCertificateDerretournetrue. - Si
enforcedHostsest renseigné (ex:{'ota.saramoney.com'}), le pinning n'est imposé que sur ces domaines précis ; s'il est vide, il s'applique à tous les hôtes.
Activation globale avec HttpOverrides.global
import 'dart:io';
import 'package:tk_ota_push/tk_ota_push.dart';
void configureTlsPinning() {
final pinner = OtaCertificatePinner(
pinnedSha256Fingerprints: {
'42d889f8f4b6bf9d3abb767d3b5f215e0009e4d26cb7b958497e8b291e1b96dc',
},
enforcedHosts: {'ota.saramoney.internal'},
);
HttpOverrides.global = OtaPinnedHttpOverrides(pinner);
}
5. Comportements en cas d'échec (OtaSecurityVerdict)
Lors de l'appel à ota.syncWithRemoteConfig(...), l'évaluation de sécurité s'exécute à l'Étape 0b, avant même d'interroger le RemoteConfigGatekeeper ou le réseau :
Type de violation (OtaSecurityViolationType) | Cause | Comportement du SDK |
|---|---|---|
apkSignatureMismatch | Signature SHA-256 de l'APK absente ou absente de expectedApkSignaturesSha256. | 1. Appelle onSecurityViolation(verdict) si défini.2. Retourne OtaSyncOutcome avec executionMode: OtaUpdateExecutionMode.blockedBySecurityShield et networkCallPerformed: false. |
deviceRootedOrJailbroken | blockRootedOrJailbrokenDevices == true et un binaire/dossier de Root ou Jailbreak est détecté. | 1. Appelle onSecurityViolation(verdict) si défini.2. Retourne OtaSyncOutcome avec executionMode: OtaUpdateExecutionMode.blockedBySecurityShield et networkCallPerformed: false. |
tlsCertificatePinningMismatch | Certificat X.509 serveur rejeté lors de la négociation TLS. | La connexion HTTPS échoue immédiatement avant tout transfert de données. |