KikeReto / InAppPurchase-Android

1 stars 4 forks source link

Order of elements in original json #1

Open Igor-lkm opened 10 years ago

Igor-lkm commented 10 years ago

Good day thanks for the great plugin!

1) Order of elements in original json

My goal was to make server side verification. (openssl_verify)

When i tried to verify i always get 0.

I spent a couple of days to figure it out.

inappbilling.getPurchases(success, fail) returns payload with wrong order of keys.

I had: purchaseToken, packageName, purchaseState, orderId, purchaseTime, productId from getPurchases.

So verification fails with this json.

We need original structure: orderId, packageName, productId, purchaseTime, purchaseState, purchaseToken

To fix it in javascript, before sending to server:

inappbilling.getPurchases(function(result) {

  var signature = result[0].signature;
  var payload = result[0].payload;

  var originalJson = {};
  originalJson.orderId = payload.orderId;
  originalJson.packageName = payload.packageName;
  originalJson.productId = payload.productId;
  originalJson.purchaseTime = payload.purchaseTime;
  originalJson.purchaseState = payload.purchaseState;
  originalJson.purchaseToken = payload.purchaseToken;

}, fail, skus)

2) And samll issue

In documentation said we can user

inappbilling.init(success, error, options)

or

inappbilling.init(success, error, options, skus)

But in my project, when i tried to make inappbilling.init(success, error, options) i get an error.

So I used inappbilling.init(success, error, options, skus).

KikeReto commented 10 years ago

Hello!

Thanks a lot!

The documentation of Google is wrong, 0 is correct, and 1 is a bad purchase!

I struggled for a week with this problem...

El 02/05/14 10:01, Igor Likhomanov escribió:

Good day thanks for the great plugin!

1) Order of elements in original json

My goal was to make server side verification. (openssl_verify)

When i tried to verify i always get 0.

I spent a couple of days to figure it out.

inappbilling.getPurchases(success, fail) returns payload with wrong order of keys.

I had: purchaseToken, packageName, purchaseState, orderId, purchaseTime, productId from getPurchases.

So verification fails with this json.

We need original structure: orderId, packageName, productId, purchaseTime, purchaseState, purchaseToken

To fix it in javascript, before sending to server:

var originalJson = {}; originalJson.orderId = payload.orderId; originalJson.packageName = payload.packageName; originalJson.productId = payload.productId; originalJson.purchaseTime = payload.purchaseTime; originalJson.purchaseState = payload.purchaseState; originalJson.purchaseToken = payload.purchaseToken;

2) And samll issue

In documentation said we can user

inappbilling.init(success, error, options)

or

inappbilling.init(success, error, options, skus)

But in my project, when i tried to make inappbilling.init(success, error, options) i get an error.

So I used inappbilling.init(success, error, options, skus).

— Reply to this email directly or view it on GitHub https://github.com/KikeReto/InAppPurchase-Android/issues/1.

mohamnag commented 10 years ago

I dont get how the order of fields can be of any matter! you are dealing with JSON, the field order does not matter.

Igor-lkm commented 10 years ago

@mohamnag not exactly.

When we execute on server-side (php in my case)

openssl_verify ($data, $signature, $key)

then $data is not a JSON object, it's a string.

openssl_verify verifies that the signature is correct for the specified string.

So if order of elements in $data, is different to original - it's other string. Verification will be failed.

If we do this:

inappbilling.getPurchases(function(result) {
     var payload = result[0].payload;
    /* post payload to server side  ... */
}, fail, skus)

Then payload variable has not the original order (it's a JSON, no order). When we post it to the server-side - we get the string, and the order of elements in this string is not original too, but on server side we need the original string.

So before sending it to server-side - we have to make the original order in our string.

mohamnag commented 10 years ago

but why you are using the signature for verification at all? why dont you got directly to google's server for verification? https://developers.google.com/android-publisher/v1_1/

If I'm not wrong, this signature verification is mainly meant for offline verification and for the cases where you dont have a backend to support you.

Igor-lkm commented 10 years ago

@mohamnag It's possible to verify Purchase with signature or api. Google recommends to do verification on backend server in both cases.

Google recommendations about security.

Signature

http://developer.android.com/google/play/billing/billing_integrate.html

To help ensure the integrity of the transaction information that is sent to your application, Google Play signs the JSON string that contains the response data for a purchase order. Google Play uses the private key that is associated with your application in the Developer Console to create this signature. The Developer Console generates an RSA key pair for each application.

When your application receives this signed response you can use the public key portion of your RSA key pair to verify the signature. By performing signature verification you can detect responses that have been tampered with or that have been spoofed. You can perform this signature verification step in your application; however, if your application connects to a secure remote server then we recommend that you perform the signature verification on that server.

http://developer.android.com/google/play/billing/billing_best_practices.html

If practical, you should perform signature verification on a remote server and not on a device.

PHP code: https://gist.github.com/menny/1985010#file-verify_market_in_app-php

API

If you whant to do this with API, Google recommends to do it on backend server too:

http://developer.android.com/google/play/billing/gp-purchase-status-api.html

To verify a purchase, the app passes the purchase token and other details up to your backend servers, which verifies them directly with Google Play using the Purchase Status API. For security reasons, the app should not normally attempt to verify the purchase itself using the Purchase Status API.

As for me signature + php looks more simple.

KikeReto commented 10 years ago

I am using two ways, first checking the signature, and later google verification.

mohamnag commented 10 years ago

Just thought it can be an overkill!

KikeReto commented 10 years ago

in five times the people try to hack inapp... better overkill than free products :smile: