7

i'm trying android in app billing v3 verifying on my remote php server.

but, it seems something is wrong at my codes.

i think this openssl_verify function is problem.

result is always failed!

i can't find what first parameter to verify with openssl_verify. actually, i 'm confuse what's reasonable format to place at first parameter :(

could you help me to solve it?

    $result = openssl_verify($data["purchaseToken"], base64_decode($signature), $key); // original // failed

belows full test codes.

    <?php
    $responseCode = 0;
    $encoded='{
            "orderId":"12999763169054705758.1111111111111",
                    "packageName":"com.xxx.yyy",
                    "productId":"test__100_c",
                    "purchaseTime":1368455064000,
                    "purchaseState":0,
                    "purchaseToken":"tcmggamllmgqiabymvcgtfsj.AO-J1OwoOzoFd-G-....."
}';
$data = json_decode($encoded,true);

$signature = "tKdvc42ujbYfLl+3sGdl7RAUPlNv.....";

$publicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2kMri6mE5+.....";

$key = "-----BEGIN PUBLIC KEY-----\n" . chunk_split($publicKey, 64, "\n") . "-----END PUBLIC KEY-----";
$key = openssl_get_publickey($key);
if (false === $key) {
        exit("error openssl_get_publickey");
}
var_dump($key);

$result = openssl_verify($data["purchaseToken"], base64_decode($signature), $key); // original // failed
//$result = openssl_verify($data, base64_decode($signature), $key); // failed
//$result = openssl_verify($encoded, base64_decode($signature), $key); // failed
//$result = openssl_verify(base64_decode($data["purchaseToken"]), base64_decode($signature), $key); // failed
//$result = openssl_verify(base64_decode($signature),$data["purchaseToken"],  $key,OPENSSL_ALGO_SHA512 ); // failed
if ($result == 1) {
        echo "good";
} elseif ($result == 0) {
        echo "bad";
} else {
        echo "error";
}
echo($result);

thanks :)

TaeL
  • 1,026
  • 9
  • 17

1 Answers1

8

You are passing the wrong $data value into openssl_verify(). This value should be the full JSON string you get from Google Play, not the purchase token inside it. It is important that the JSON string is untouched, as even if you were to add a space or newlines to it, the signature would no longer work.

All you need to do in your code above is to change this line:

$result = openssl_verify($data["purchaseToken"], base64_decode($signature), $key);

to

$result = openssl_verify($data, base64_decode($signature), $key);

And you should get a success, assuming you're using the correct public key and the JSON purchase string is valid. I'm pretty sure your JSON string is not the original string from Google however, as the ones from Google do not contain newlines. It will be one long line of JSON text. Make sure that's what you are passing to openssl_verify().

The Awnry Bear
  • 4,599
  • 3
  • 29
  • 33
  • +1 for two things, parameters, and wrong json string. i corrects both, and fixed. thanks – TaeL Jun 26 '13 at 08:41
  • it is a bit confusing because in your answer `$data` is decoded json to array. It is important to use ORIGINAL JSON from Google (I know that it is in your answer at the end, but I missed it during first reading :-) ) – Naxos May 12 '14 at 13:32
  • Do you have enough rep to improve the answer? If so by all means please do. Otherwise, I'll try to update it to clarify it better. :) – The Awnry Bear May 13 '14 at 02:04