2

After successful purchase I save receipt+transactionID into NSUserDefaults. Same information is sent to server to keep a record.

Later(on demand) when user want to download content from my own server, my app will send receipt+transactionID to server. It will find stored receipt by transaction ID sent from app, verify both stored and new receipts with Apple. If some of the keys matched then provide downloadable content.

However, nowadays it's not hard to get hold of NSUserDefaults and extract receipt+transactionID. Even if I place information in keychain, it's possible to capture receipt from internet connection.

Now if someone will have receipt+transactionID, can send a request to my server and get content from any PC. How can I patch this logic without using cryptography?

Rajesh
  • 850
  • 9
  • 18
Pablo
  • 28,133
  • 34
  • 125
  • 215
  • 4
    You can patch this logic to make it harder to bypass, but you wouldn't be able to make it bullet-proof without using cryptography. Place info into keychain (it's made for storing sensitive information of that kind), and use https to communicate with the server to protect the transport of your keys. That's all the cryptography that you need - at this point, it would probably be less expensive to buy your content than to break your protection. – Sergey Kalinichenko Feb 20 '14 at 13:17
  • The receipt validation mechanism itself using transactionID which I described, does it make sense or I am over complicating it? – Pablo Feb 20 '14 at 13:20
  • Your verification scheme does not look objectionable, as long as you protect the keys on the device and en route to your server. – Sergey Kalinichenko Feb 20 '14 at 13:33
  • You can copy this as an answer if you think this is the only way and if there are no better answers I will accept it. thanks. – Pablo Feb 20 '14 at 13:44

1 Answers1

4

Although you can patch your logic to make it harder to break, if you want real protection you need some kind of cryptography. You do not need to apply it explicitly - something as mainstream as switching from HTTP to HTTPS will often do the trick.

The three places where you need to protect your sensitive data are on the device, on the server, and in transit.

To protect the data on the device, store it in the Keychain: after all, storing small chunks of sensitive data is the main purpose of adding Keychain to the array of storage possibilities on iOS.

Server protection is a large topic that has been treated in numerous online and offline publications; for the purpose of this answer I assume that your server is adequately secured.

What is left is protection of your data in transit between the device and the server, and between your server and the Apple's server. You can use HTTPS for achieving transport-level protection.

Note that adding all these levels of protection does not make your data absolutely secure: an entity with a lot of time and resources (e.g. a government of an unfriendly country) could potentially discover your keys - for example, by disassembling the physical device, and inspecting the data coming out of the CPU with a logic analyzer. However, the point of this exercise is not to achieve the absolute protection, but to make it prohibitively expensive to break your security scheme. To that end, a combination of Keychain and HTTPS should achieve the goal of making it more expensive to break your protection than to buy your content legally.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • The part of the scheme that should persist receipt on device, perhaps using keychain, is only true for iOS 6.1 or earlier, is that right? Because from what I read it's possible to decrypt iOS7 App receipt and find in-app purchase there. So it persists in App receipt anyway. Does it make sense? – Pablo Feb 21 '14 at 14:03
  • @Pablo I cannot find any info on iOS7 app receipt vulnerability. Do you have a link? I did find lots of links for the pre-iOS 6 vulnerability, but it would not have any effect on you, because you validate on your own server. – Sergey Kalinichenko Feb 21 '14 at 14:18
  • No it is not vulnerable, neither I saw that app receipt ever compromised. My question was rather for validation scheme. For iOS7 only I can skip the part of persisting receipt+TransactionID and take them from app receipt, then send them to my server. `TransactionReceipt` property is deprecated in iOS7 anyways... – Pablo Feb 21 '14 at 14:24
  • @Pablo That's true, the validation scheme in iOS 7 has changed so that you do not need to store transaction receipt. This lets you perform validation entirely on the device if you wish, skipping a trip to your server. – Sergey Kalinichenko Feb 21 '14 at 14:42
  • Oh, the "entirely" part put my scheme under big question. I can certainly validate app receipt on iOS7, but at the end of the day I have to send verification items to the server in order to be able download content. I am not sure if iOS7 in-app purchase payload is extractable and can be sent back to Apple(through my server) for validation. iOS7 scheme totally puzzled me... – Pablo Feb 21 '14 at 14:49