If I offload verification to a remote server, I think the process will be something like:
Android Market Application Remote Server
|--------IN_APP_NOTIFY------->| |
| |-----nonce----->|
| |<----nonce------|
|<-GET_PURCHASE_STATE_CHANGED-| |
|---PURCHASE_STATE_CHANGED--->| |
| |--verification->|
| |<-verification--|
If I understand correctly, the nonce is to reduce replay attack vulnerability and the verification is to reduce spoofing vulnerability. Also, the reason the docs recommend offloading security processing is that the verification step requires access to my public Android Market publisher's key and the goal of the remote server is to keep said key from needing to be included/computed in my code.
First question, is there a security reason for the remote server to do the nonce generation/check? Pressuming the verification step is done correctly, we'd find out from the remote server if the message was spoofed. So it seems to me that the nonce is just there to detect someone rebroadcasting the IN_APP_NOTIFY.
Second question, why does it matter if our public key is a literal string? The docs say, "you do not want to make it easy for a hacker or malicious user to replace the public key with another key." I'm not clear how someone could exploit my app even if they could edit the binary to include a malicious public key without having to resign the app.
Third question, won't I have all these same problems trying to verify the verification from my remote server (e.g. storing public key to my remote server in the application)?
Fourth question, is all of this extra security for naught if I want to store the results of this purchase verification on the phone (i.e. I don't want to have to verify the purchase state of the unlocked content whenever a user accesses the content)?
First question, is there a security reason for the remote server to do the nonce generation/check?
Yes, the server should generate the nonce, and do the check. As a general rule, everything security-related should almost allways be done in the server. A nonce is a "number only used once". So, the correct thing for the server is to:
Second question, why does it matter if our public key is a literal string?
A little if you perform security checks on the aplication, completly irrelevant if you do your work on a server (as you should).
If you perform security in the aplication, then the aplication can be hacked to bypass the security. One technique is to change the public key, wich is easier if it is saved as a single string.
Third question, won't I have all these same problems trying to verify the verification from my remote server (e.g. storing public key to my remote server in the application)?
No you won't. No one can access/change the code of the server. At least as "easy" as the can in the aplication.
Fourth question, is all of this extra security for naught if I want to store the results of this purchase verification on the phone (i.e. I don't want to have to verify the purchase state of the unlocked content whenever a user accesses the content)?
Well, it depends.
The "securest" way to implement in-app purchases having a server implies:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With