从服务器端验证谷歌播放购买

cre*_*tor 5 php openssl unity-game-engine in-app-purchase

我现在真的搞砸了理解需求的概念和原因,甚至不知道如何通过编码来实现.

所以,我用团结制作手机游戏,c#.使用php,mysql进行高分,并在应用程序购买项目信息中存储用户.

我一周前在google play上发布了我的游戏,我的谷歌钱包显示没有人,直到现在购买该游戏中的任何项目.

但是,当我检查我的游戏服务器(mysql数据库)时,一些用户有大量应该购买的项目.

这意味着一些用户使用黑客工具并绕过谷歌游戏检查过程并欺骗我的游戏并进行假购买.

所以我没有实现developerPayload,也没有验证google play购买收据.

所以现在我删除了我的数据库中的整个恶意用户的项目(这将设置0到该用户的客户端项目),并且想要实现google play购买收据的服务器端验证.

我通过谷歌搜索搜索了许多帖子,但从头到尾没有完美的解决方案.

无论如何,我到目前为止实现了这样的.

首先,在用户结束谷歌结账过程(无论这是真的还是假的)之后,我的Unity客户端的OnPurchaseSucceded函数被调用,在那里我实现了开始在我的服务器上传递我的PHP脚本.

 private void OnPurchaseSucceded(Purchase purchase)
{
    /*
    // Optional verification of the payload. Can be moved to a custom server
    if (!VerifyDeveloperPayload(purchase.DeveloperPayload)) {
        return;
    }*/
    StartCoroutine(VerifyReceiptCo(purchase));
}

 IEnumerator VerifyReceiptCo(Purchase purchase)
{
    WWWForm hsFm = new WWWForm();
    hsFm.AddField("data", purchase.OriginalJson);
    hsFm.AddField("signature", purchase.Signature);
    WWW hs = new WWW(verifyURL, hsFm);
    yield return hs;
    Debug.Log("verify result is " + hs.text);
    // if result is true(validated), give item to user.
}
Run Code Online (Sandbox Code Playgroud)

在这里问题,

1. [我在代码上方做得对吗?对于"数据"字段,我使用了buy.OriginalJson,但这是对的吗?如果没有,我该怎么用?]

并从php(上述代码的verifyURL)收到这些信息后,

$base64EncodedPublicKey = "MY game's public key from google play console";
$signedData =  $_POST['data'];
$signature =  $_POST['signature']; 

$key = openssl_pkey_get_public($base64EncodedPublicKey);
$verified = (openssl_verify($signedData, base64_decode($signature), $key, OPENSSL_ALGO_SHA1) > 0);
$result = openssl_verify($signedData, base64_decode($signature), $key, OPENSSL_ALGO_SHA1);
if ($verified) {
    echo 'verified : result is'.$result;
} else {
    echo 'fail : result is'.$result;
}
Run Code Online (Sandbox Code Playgroud)

另一个问题,

2. [我是否需要使用付费SSL服务来使用上面的php代码之类的openssl_方法?]我正在使用hostgator.com的网络托管,我的计划已经有了"共享SSL"服务,那么这就足够了吗?或者我应该购买另一个私人SSL服务计划?]

3.如果不使用openssl(不使用SSL服务)方法,是否无法验证这一点?

总体而言,我是否正确地指导黑客用户?非常感谢.

小智 1

这是我验证谷歌订单的代码。它与我公司的所有产品配合良好。非常简单的代码。

    function verifyGoogleOrderLocal($packageName, $jsonData, $sig)
{
    $public_keys = array(
    'package1' => 'key1',
    'package2' => 'key2',
    );
    if(!$public_keys[$packageName]) {
        return array("success"=>0,"reason"=>'no public key defined');
    }
    $key = get_openssl_key($public_keys[$packageName]);
    if(!$key) {
        return array("success"=>0,"reason"=>'invalid public key');
    }
    $result = openssl_verify($jsonData, base64_decode($sig), $key, OPENSSL_ALGO_SHA1);
    $resp = array('success'=>$result);
    if($result==0) $resp['reason'] = 'invalid signature'; 
    return $resp;
}

function get_openssl_key($publicKey)
{
    $key = "-----BEGIN PUBLIC KEY-----\n" . chunk_split($publicKey, 64, "\n") . '-----END PUBLIC KEY-----';
    $key = openssl_get_publickey($key);
    return $key;
}
Run Code Online (Sandbox Code Playgroud)