'How to verify unity's GooglePlay in app billing signature?
from unity reference, to verify an in-app purchase(GooglePlay), we should get Payload from Receipt, then verify Payload.json(INAPP_PURCHASE_DATA) and Payload.signature(INAPP_DATA_SIGNATURE) like this:
const (
cGooglePubKey = "MIIBIjANBgkqhki...............AQAB"
)
var (
data = `{\"orderId\":\"GPA.A-B-C-D\",\"packageName\":\"com.x.y\",\"productId\":\"pdt1\",\"purchaseTime\":1653297088926,\"purchaseState\":0,\"purchaseToken\":\"xxxxx\",\"acknowledged\":false}`
sign = "R6U/cmXT...RfOg=="
)
func main() {
if ok, err := validateGooglePay(data, sign, cGooglePubKey); ok {
println("YES!!")
} else {
println(err.Error())
}
}
func validateGooglePay(purchaseData string, signature string, publicKey string) (bool, error) {
decodePublic, err := base64.StdEncoding.DecodeString(publicKey)
if err != nil {
return false, err
}
pubInterface, err := x509.ParsePKIXPublicKey(decodePublic)
if err != nil {
return false, err
}
pubKey, _ := pubInterface.(*rsa.PublicKey)
decodeSign, err := base64.StdEncoding.DecodeString(signature)
if err != nil {
return false, err
}
sh1 := sha1.New()
sh1.Write([]byte(purchaseData))
hashData := sh1.Sum(nil)
result := rsa.VerifyPKCS1v15(pubKey, crypto.SHA1, hashData, decodeSign)
if result != nil {
return false, result
}
return true, nil
}
But I failed with "crypto/rsa: verification error"! And WHY?
I even use PHP to test, still failed:
<?php
if (checkGpBilling() !== true) {
print("FAILED\n");
}
function checkGpBilling() {
$inappPurchaseData = '{\"orderId\":\"GPA.A-B-C-D\",\"packageName\":\"com.x.y\",\"productId\":\"pdt2\",\"purchaseTime\":1653297088926,\"purchaseState\":0,\"purchaseToken\":\"hmj...f3A\",\"acknowledged\":false}';
$inappDataSignature = 'R6U/cmX...RfOg==';
$googlePublicKey = 'MIIBIjANBgkqhki...AQAB';
$publicKey = "-----BEGIN PUBLIC KEY-----". PHP_EOL .
chunk_split($googlePublicKey, 64, PHP_EOL) .
"-----END PUBLIC KEY-----";
$publicKeyHandle = openssl_get_publickey($publicKey);
$result = openssl_verify($inappPurchaseData, base64_decode($inappDataSignature), $publicKeyHandle, OPENSSL_ALGO_SHA1);
if (1 !== $result) {
print($result);
return false;
}
return true;
}
Can anyone correct me if i was wrong, or please tell me the right way/code? thanks very much!
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
