I have read a lot of docs and code that in theory will validate an in-app and/or bundle receipt.

Given that my knowledge of SSL, certificates, encryption, etc., is nearly zero, all of the explanations I have read, like this promising one, I have found difficult to understand.

They say the explanations are incomplete because every person has to figure out how to do it, or the hackers will have an easy job creating a cracker app that can recognize and identify patterns and patch the application. OK, I agree with this up to a certain point. I think they could explain completely how to do it and put a warning saying "modify this method", "modify this other method", "obfuscate this variable", "change the name of this and that", etc.

Can some good soul out there be kind enough to explain how to LOCALLY validate, bundle receipts and in-app purchase receipts on iOS 7 as I am five years old (ok, make it 3), from top to bottom, clearly?

Thanks!!!

If you have a version working on your apps and your concerns are that hackers will see how you did it, simply change your sensitive methods before publishing here. Obfuscate strings, change the order of lines, change the way you do loops (from using for to block enumeration and vice-versa) and things like that. Obviously, every person that uses the code that may be posted here, has to do the same thing, not to risk being easily hacked.

Fair warning: doing it locally makes it a hell of a lot easier to patch this function out of your application.
–
NinjaLikesCheezNov 15 '13 at 13:57

OK, I know, but the point here is to do things difficult and prevent automated cracking/patching. The question is that if a hacker really wants to crack your app he/she will do it, whatever method you use, local or remote. The idea is also to change it slightly every new version you release, to prevent automated patching again.
–
SpaceDogNov 15 '13 at 14:01

2

@NinjaLikesCheez - one can NOP the check even if the verification is done on a server.
–
SpaceDogNov 15 '13 at 17:33

sorry, but this is not excuse. The only thing the author has to do is to say DO NOT USE THE CODE AS IT IS. Without any example, it is impossible to understand this without being a rocket scientist.
–
SpaceDogNov 25 '13 at 18:15

Getting the receipt data

The receipt is in [[NSBundle mainBundle] appStoreReceiptURL] and is actually a PCKS7 container. I suck at cryptography so I used OpenSSL to open this container. Others apparently have done it purely with system frameworks.

Adding OpenSSL to your project is not trivial. The RMStore wiki should help.

If you opt to use OpenSSL to open the PKCS7 container, your code could look like this. From RMAppReceipt:

It should be noted that certain in-app purchases, such as consumables and non-renewable subscriptions, will appear only once in the receipt. You should verify these right after the purchase (again, RMStore helps you with this).

Verification at a glance

Now we got all the fields from the receipt and all its in-app purchases. First we verify the receipt itself, and then we simply check if the receipt contains the product of the transaction.

Verifying the receipt

Checking that the receipt is valid PKCS7 and ASN1. We have done this implicitly already.

Verifying that the receipt is signed by Apple. This was done before parsing the receipt and will be detailed below.

Checking that the bundle identifier included in the receipt corresponds to your bundle identifier. You should hardcode your bundle identifier, as it doesn't seem to be very difficult to modify your app bundle and use some other receipt.

Checking that the app version included in the receipt corresponds to your app version identifier. You should hardcode the app version, for the same reasons indicated above.

Check the receipt hash to make sure the receipt correspond to the current device.

Verifying the receipt signature

Back when we extracted the data we glanced over the receipt signature verification. The receipt is signed with the Apple Inc. Root Certificate, which can be downloaded from Apple Root Certificate Authority. The following code takes the PKCS7 container and the root certificate as data and checks if they match:

Thanks for recommending my library. I will try to post a walkthrough of the code later as links tend to get broken.
–
hpiqueNov 18 '13 at 2:21

I would love to see it supporting downloads of content that is hosted at apple. On the mean time I would like to know if there is a way to implement just the verify receipt part without using the whole RMStore stuff. This is because your library doesn't support downloads and I need to support that on my app and I still have a code in place to manage all the purchase and download. All I need now is to verify the receipts.
–
SpaceDogNov 18 '13 at 6:09