web-dev-qa-db-fra.com

Code de validation des reçus du Mac App Store?

Vous vous demandez si quelqu'un a un didacticiel ou un code de travail pour la validation des reçus du nouveau Mac App Store? Les seules références que j'ai pu trouver jusqu'à présent sont la documentation stellaire d'Apple sur le sujet et un projet open source qui compile mais n'a pas beaucoup de commentaires en ligne, donc il est difficile à comprendre à moins que vous ne soyez un as de la crypto.

Apple docs pour les développeurs enregistrés uniquement:

https://developer.Apple.com/devcenter/mac/documents/validating.html

Rodate ValidateStoreReceipt (semble prometteur, mais peu documenté):

https://github.com/roddi/ValidateStoreReceipt

Aussi, vous vous demandez pourquoi Apple ne fournit pas simplement du code fonctionnel pour la validation?

Y a-t-il d'autres bonnes références?

39
Rei

Il est difficile de fournir une solution générique pour la validation des reçus du Mac App Store, principalement parce qu'il s'agit d'un morceau de code très sensible qui doit être difficile à contourner (cf. Documentation Apple ).

Ces projets GitHub sont de très bons points de départ pour savoir quelles étapes doivent être exécutées lors de la validation de la réception:

Une fois que vous avez compris ce qui doit être fait, voici quelques conseils:

  • N'utilisez pas de classes ou de méthodes Objective-C. Objective-C contient beaucoup de métadonnées et sa nature dynamique l’expose à l’injection en temps réel.
  • Utilisez uniquement des appels de fonction C. Même si vous avez besoin de davantage de lignes de code avec le framework CoreFoundation, vous pouvez parfaitement faire ce que le framework Foundation peut faire (NSString, NSArray, NSDictionary, ...).
  • Ne créez pas de lien dynamique avec la bibliothèque OpenSSL car elle est obsolète dans Mac OS X Lion. Si vous voulez utiliser OpenSSL , liez-le statiquement pour vous assurer de disposer de la dernière version.
  • Utilisez les fonctions système pour la cryptographie. Mac OS X est fourni avec des fonctions équivalentes depuis 10.5. Par exemple, pour calculer un hachage SHA-1, vous pouvez utiliser la fonction CC_SHA1 .
  • Ne mettez pas de chaînes en texte clair dans votre code. Encodez-les ou cryptez-les. Si vous ne le faites pas, vous donnez un indice sur l'emplacement de votre code.
  • N'utilisez pas de constantes numériques dans votre code. Calculez-les au moment de l'exécution, avec quelques opérations simples (+, -,/ou *). Encore une fois, si vous ne le faites pas, vous donnez un indice sur l'emplacement de votre code.
  • Évitez les tests simples de validation en incorporant vos tests et l'appel à NSApplicationMain dans une boucle complexe.
  • Évitez d'appeler NSApplicationMain directement. Utilisez un pointeur de fonction pour masquer l'invocation. Si vous ne le faites pas, vous donnez un indice sur l'emplacement de votre code.
  • Pour chaque version de votre application, modifiez légèrement le code de validation afin qu’il ne soit plus jamais le même.

N'oubliez pas que la validation du reçu est nécessaire et qu'elle n'est pas simple. Cela peut prendre beaucoup de temps que vous pourriez mieux utiliser pour votre application.

Donc, je vous suggère de jeter un oeil à cette application: Receigen (Avertissement: je suis le développeur de cette application).

29
Laurent Etiemble

Afin de valider la réception réelle après le test, modifiez cette ligne de code dans votre fichier main.m :

if (!validateReceiptAtPath(@"~/Desktop/receipt"))

à

#ifdef USE_SAMPLE_RECEIPT   // defined for debug version
    NSString *pathToReceipt = @"~/Desktop/receipt";
#else
    NSString *pathToReceipt = [[[NSBundle mainBundle] bundlePath]
        stringByAppendingPathComponent:@"Contents/_MASReceipt/receipt"];
#endif  
    if (!validateReceiptAtPath(pathToReceipt))
        exit(173); //receipt did not validate

et dans les paramètres de votre compilateur, "Other C Flags" pour votre configuration de débogage devrait inclure -DUSE_SAMPLE_RECEIPT

courtoisie http://jesusagora.org/groups/futurebasic/0::53562:get:1read.html

6
snibbe

Assurez-vous que vous validez un reçu pour votre application. Facile à faire toute la crypto et vérification des signatures pour le reçu faux.

Voir http://Pastebin.com/1eWf9LCg où il semblerait qu'Angry Birds ait raté ce passage et les ait laissés ouverts aux personnes remplacées par un reçu d'une application gratuite.

Alan Quatermain a aussi du code pour le faire sur github. https://github.com/AlanQuatermain/mac-app-store-validation-sample

Il ne doit pas être utilisé tel quel pour éviter le retrait automatisé. 

5
koregan

Vous pouvez essayer NPReceiptVerification . C'est le moyen le plus simple d'ajouter une vérification de reçu à votre application. Vous ajoutez simplement les fichiers de classe à votre projet, définissez la version et l'identificateur de l'ensemble, et tout le reste est géré automatiquement. 

3
indragie

J'ai relu le code d'Alan Quartermain et ça a l'air bien. Quelque chose à quoi penser:

le dernier paramètre ici pourrait/devrait être une exigence compilée indiquant que le code doit être signé par VOTRE certificat et par personne d'autre.

Lorsque le développeur soumet une application à la boutique pour approbation, les certificats de signature sont les suivants:

3rd Party Mac Developer Application: me
Apple Worldwide Developer Relations Certification Authority
Apple Root CA

Une fois l'application fournie à l'utilisateur final depuis l'App Store, les certificats de signature sont les suivants:

Apple Mac OS Application Signing
Apple Worldwide Developer Relations Certification Authority
Apple Root CA

De plus, je suggère de ne quitter (173) que lorsque le reçu est manquant, mais tout le reste est en ordre.

3
C0C0AL0C0

Je proposerais d'implémenter les routines de vérification de code en tant que fonctions C , pas de méthodes ObjC. 

Cette technique rend (un peu) plus difficile la localisation du code de vérification de la réception, car moins de noms de méthodes sont compilés dans le binaire. 

2
SteAp

Vous pouvez vous référer à RVNReceiptValidation il est facile à mettre en œuvre. Il vous suffit de définir l'identifiant du paquet dans le fichier RVNReceiptValidation.m et la version de votre application. N'oubliez pas d'obtenir le reçu de la part de Apple, vous devez lancer l'application depuis le Finder. Cette classe aide également à la mise en œuvre de l'achat InApp.

2
Aravindhan

Lors de la création de l'exemple de facture à partir d'Apple Docs, veillez à ne pas inclure de caractères supplémentaires après "end", sinon le code uudecode échouera.

1
pygar

Je vais élaborer sur la réponse de Priller. Si Apple fournissait un exemple de code pour le processus de validation, il serait très facile pour un méchant de prendre votre application compilée et de la parcourir pour rechercher le code correspondant au processus de validation. Le méchant sait exactement à quoi ressemble le code compilé si vous utilisez un exemple de code standard d'Apple. Une fois que le méchant a trouvé cette partie du code, il est assez simple de modifier le code compilé de l'application pour ignorer l'étape de vérification des reçus, ce qui rend la chose totalement inutile.

Cela dit, un pirate déterminé va probablement contourner toute protection contre la copie que vous mettez en place, peu importe ce que vous faites. L'industrie du jeu (par exemple) passe beaucoup de temps à essayer de protéger son logiciel et les versions fissurées semblent toujours disponibles.

1
Pete Hodgson

Oui, dans leur documentation, il est indiqué: "Il est important que vous utilisiez une solution unique pour votre application."

0
priller

Même avec NPReceiptValidation, vous devez toujours valider la sécurité de votre groupe d'applications, y compris les certificats de signature. Ceci est documenté dans les recommandations du WWDR pour les développeurs.

Une solution: http://iTunes.Apple.com/us/app/apptight-pro-app-store-code/id427083596?mt=12

Un problème potentiel avec NPReceiptValidation est que les sélecteurs de méthodes sur les objets Cocoa sont très faciles à détourner. C'est le moyen le plus populaire d'étendre les applications.

Voici un autre outil d'aide à l'analyse syntaxique des achats intégrés:

http://iTunes.Apple.com/us/app/pkcs-7viewer/id547539804?mt=12

0
C0C0AL0C0

le validateStoreReceipt de roddi a déjà fonctionné pour moi auparavant, mais il ne fonctionne plus. J'ai écrit un article sur la solution: http://vinceyuan.blogspot.com/2012/07/validate-mac-app -store-reception-2012.html

Copié ici: Le code de Roddi fonctionne toujours. Vous n'avez pas besoin de le changer. (Juste besoin d’obtenir la dernière version) Suivez ces étapes (internet requis):

  1. Déconnectez-vous de l'application Mac App Store.
  2. Supprimez l'indicateur USE_SAMPLE_RECEIPT des paramètres de votre projet -> Macros de préprocesseur.
  3. Compilez votre projet
  4. Trouvez cette application dans le Finder
  5. Double-cliquez dessus dans le Finder pour s'exécuter. Ne l'exécutez pas dans Xcode.
  6. Le système d'exploitation vous demandera de vous connecter avec votre identifiant Apple. Ne vous connectez pas avec votre vrai compte iTunes. Vous devez vous connecter avec le compte test. Trouvez-le ou créez-le sur le site Web iTunesconnect.
  7. Le système d'exploitation indiquera quelque chose comme "Votre application est endommagée. Téléchargez-la sur l'App Store". Ignorer ce message. Si vous "Afficher le contenu du paquet" de cette application dans le Finder, vous verrez qu'il existe un fichier _MASReceipt/receive. Le système d'exploitation a installé un reçu de développement. Nous n’aurons plus besoin de l’ancien échantillon reçu. C'est pourquoi nous supprimons l'indicateur de débogage USE_SAMPLE_RECEIPT.

Terminé. Vous pouvez déboguer votre application maintenant.

0
Vince Yuan

RVNReceiptValidation est génial et utilise CommonCrypto plutôt que le désormais obsolète Apple, openssl. vous devrez joindre un reçu valide à votre projet pour le déboguer. Pour ce faire, obtenez un reçu valide d'un autre ensemble d'applications et créez une phase de construction dans votre environnement de test afin de l'ajouter à votre ensemble. Je suggère les techniques suivantes pour l'obscurcissement:

Cryptez kRVNBundleID et kRVNBundleVersion et déchiffrez-les lorsque vous les comparez à CFBundleIdentifier et CFBundleShortVersionString.

Je crée un tableau de pointeurs de fonction avec des valeurs aléatoires et les change en pointeurs valides vers les fonctions de RVNReceiptValuation au moment de l'exécution avant de les exécuter à l'aide d'un code comme celui-ci:

static void testFunction(void);

typedef void (*functionPtr)(void);

functionPtr obfuscationArray[8] = {
    (functionPtr)0xA243F6A8,
    (functionPtr)0x885308D3,
    (functionPtr)0x13198A2E,
    (functionPtr)0x03707344,
    (functionPtr)0xA4093822,
    (functionPtr)0x299F31D0,
    (functionPtr)0x082EFA98,
    (functionPtr)0xEC4E6C89};

int main(int argc, const char * argv[]) {
    functionPtr myFuncPtr;

    obfuscationArray[3] = &testFunction;
    myFuncPtr = obfuscationArray[3];
    (myFuncPtr)();

    return 0;
}

static void testFunction(void){
    printf("function executed\n");
}
0
Billy Bob