Categories
Non classé

Mac App Store: vérifier le reçu

Dans l‘article précédent, je vous expliquai comment maintenir à la fois une version de votre application pour le Mac App Store et pour votre site web. Dans le présent article, nous verrons comment se prémunir du piratage de l’application en validant le reçu fourni par Apple.

Le reçu

Un répertoire _MASReceipt est incorporé au bundle de l’application téléchargée sur le Mac App Store:

.../SampleApp.app/Contents/_MASReceipt/receipt

Ce reçu constitue la pierre angulaire de la protection anti-pirate. Il s’agit de vérifier qu’il a bien été émis par Apple et que son contenu correspond bien à notre application. Malheureusement, Apple ne fournit pas d’API pour effectuer ces vérifications. Devant la difficulté de concevoir un service invulnérable, Apple a baissé les bras et s’est déchargée du travail sur nos épaules de développeurs. C’est donc à chaque application de faire les vérifications, qui n’ont rien de trivial!

Code d’exemple de Roddi

Apple a rédigé un document (réservé aux développeurs inscrits) qui décrit le contenu d’un reçu et les étapes de la validation. Comme vous le verrez, les indications pour l’implémentation concrète sont laconiques. Le but avoué est d’éviter que tous les développeurs utilisent le même code de validation. Le problème, c’est que peu de développeurs possèdent les connaissances nécessaires pour implémenter ces vérifications. Face à cette complexité, des développeurs ont décidé de créer une solution open-source: Roddi-ValidateStoreReceipt. On trouve aussi cet exemple d’Alan Quatermain, qui fut précurseur mais est moins abouti. Attention toutefois, il ne faut en aucun cas réutiliser ce code tel quel: il serait trop facile à repérer et modifier.

Les étapes de la validation

Comparons un peu la solution de Roddi et les préconisations d’Apple.

Vérifier la signature du reçu

Apple donne quelques indications pour vérifier la signature du reçu en utilisant OpenSSL, et indique qu’il faut utiliser le certificat Apple Root CA, mais pas comment l’obtenir. Le code de Roddi va chercher le certificat dans le Trousseau. Celui de Quatermain le récupère sur le site d’Apple, ce qui présente le défaut d’exiger un accès à Internet au lancement de l’appli.

Extraire les informations de la “Payload”

La partie “Payload” du reçu comprend les informations que nous allons vérifier par la suite: Bundle Identifier, version de l’appli, une valeur opaque (=aléatoire) et un hâchage. Apple préconise l’utilisation d’un obscur outil en ligne de commande, asn1c, pour décomposer la Payload. J’ai installé macports, installé asn1c et généré grâce à lui un fichier C permettant la décomposition.

Voici mon constat:

  • ne vous ennuyez pas à installer asn1c. Le code C qu’il a génèré est intégré au projet de Quatermain.
  • le code produit est dégueulasse. À vous les warnings de GCC dans tous les sens. Roddi a adopté une autre solution: la Payload est décomposée grâce à OpenSSL, ce qui dispense d’embarquer le code d’asn1c dans votre projet.

Vérifier le Bundle Identifier et la version

Comparez le Bundle Identifier de votre appli (pour moi, ”com.ceroce.PortraiMatic”) à celui du reçu. Ceci garantit que le reçu correspond bien à votre appli, et qu’on n’a pas remplacé le reçu de votre appli par celui d’une autre appli… (Hein, Angry Birds!) Faites de même pour la version: vous ne voudriez pas que l’utilisateur utilise le reçu de la version 1.5.3 pour valider la version 2.1.0… Il peut être tentant de récupérer ces deux informations depuis Info.plist: mauvaise idée. Ce fichier peut être modifié sans impact sur le reçu. Stockez le Bundle Identifier et la version ”en dur” dans votre code. De même, évitez — en les obscurcissant — que ces deux chaînes apparaissent quand on ouvre l’application avec un éditeur hexa. Notez que le code de Roddi compare les chaînes en dur avec celles d’Info.plist pour éviter les étourderies.

Vérifier le GUID

Le GUID est en fait l’adresse mac de l’ordinateur autorisé. Pour une fois, Apple fournit du code pour la récupérer (adopté tel quel chez Roddi). Il faut concaténer le GUID + la valeur opaque + Bundle Identifier et appliquer au tout un hâchage SHA-1. Ce hâchage doit correspondre au hâchage stocké dans la payload. !!! En conclusion Nous l’avons vu, la validation n’est pas facile. Heureusement, d’autres ont déjà essuyé les plâtres! Peut-être qu’Apple nous proposera une solution plus simple dans un avenir proche.