「Unity/課金/リモートレシート検証/phpサーバ」の版間の差分
提供: 初心者エンジニアの簡易メモ
(→phpで検証) |
(→phpで検証2) |
||
行127: | 行127: | ||
return false; | return false; | ||
} | } | ||
− | |||
return true; | return true; | ||
} | } |
2025年3月18日 (火) 19:32時点における版
サーバのsslが有効になってるか確認
if (extension_loaded('openssl')) { echo "OpenSSLは有効になっています。\n"; echo "OpenSSL バージョン: " . OPENSSL_VERSION_TEXT . "\n"; } else { echo "OpenSSLは無効になっています。\n"; }
OpenSSLは有効になっています。OpenSSL バージョン:OpenSSL 3.0.7 1 Nov 2022
サーバのopenssl_verifyが動くか確認
$ cd /tmp/ # 秘密鍵 (private.pem) openssl genpkey -algorithm RSA -out private.pem # 公開鍵 (public.pem) openssl rsa -in private.pem -pubout -out public.pem
/tmp/openssl.php
<?php $message = "これはテストメッセージです。"; // 秘密鍵の読み込み $privateKey = file_get_contents('private.pem'); $privateKeyResource = openssl_pkey_get_private($privateKey); // メッセージに署名 openssl_sign($message, $signature, $privateKeyResource, OPENSSL_ALGO_SHA256); openssl_free_key($privateKeyResource); // 署名をBase64エンコード(表示用) $signatureBase64 = base64_encode($signature); echo "生成された署名: " . $signatureBase64 . "\n"; // 公開鍵の読み込み $publicKey = file_get_contents('public.pem'); $publicKeyResource = openssl_pkey_get_public($publicKey); // 署名の検証 $verification = openssl_verify($message, $signature, $publicKeyResource, OPENSSL_ALGO_SHA256); openssl_free_key($publicKeyResource); // 結果を表示 if ($verification === 1) { echo "署名は有効です。\n"; } elseif ($verification === 0) { echo "署名は無効です。\n"; } elseif ($verification === -1) { echo "エラーが発生しました: " . openssl_error_string() . "\n"; } else { echo "エラーが発生しました。\n"; }
実行
$ php /tmp/openssl.php 生成された署名: irOD+87jrUZG7akzZBl88KAGv11ej5+sSc/6LSUoS/fB87CuTQessr+oEQBB42jmRxrtIXZVjB68dz6Job06vJn46CA8rFB77ltnyqAbDK91bDDmnzr47DjPmE9TxQLnBorx4dJWDIhr8/G6CsByDHFjCVhipJvreXp/gwRt0n69AEHQdeCp1ysVjQV4CLa4ox9a/fgAJFzSUeMcTJyuMeRoBtV1Xp9MwBABvu65FYsy2LjSzHzxXam7OKxyeMx6JW7DenLWV1d4GQeXuzsks+IrhS9hn5sQngg4jchj6mfEgOdUDHU6gQrDaIlmOEVMquhKiwj9LLZUFZmjy7Ti/w== 署名は有効です。
phpで検証
<?php $receiptJson = '{"orderId":"GPA.xxxx-xxxx-xxxx-xxxxx","productId":"product1",...}'; $signature = "xxxxxxxxxxxxGR1gohIWJpFN6WBclwMl4nCjUnQGDXIaO7CJKYATekl6VJRL12ASskYvT3YNqStbUggcRgQ2j8/SdPCAe/VdsoyT3qRO6KAgsLoi9XPiFvk0oRGhDNg6b6NyOjlZKjom5wQ46E6mSPZF/LZmJPQZ/CAdP3/5jt5uZfrrB0JBPfsNhTSNY8pAwtIWGxqZErXbr6UvaWU3n/QpFOr01RZ5YSTItNqtmQq7o1onHHHbgg4dlXjVkiZcSEb0FQZjBURg/IGLfukOUCUA+rbGvaEb/+rB76w7CbLcHE7lTn4ZV0ZNB86IAc0o90g/B4SxUqpQ=="; $signature_decode = base64_decode($signature); // 下記のURLなどを参考にpem形式に変換 // FYI: http://php.net/manual/ja/ref.openssl.php $publicKey = der2pem(base64_decode('[googleplay収益化セットアップのrsa公開鍵]')); $publicKeyResource = openssl_pkey_get_public($publicKey); // 署名の検証 $verification = openssl_verify($receiptJson, $signature_decode, $publicKeyResource); openssl_free_key($publicKeyResource); // 結果を表示 if ($verification === 1) { echo "ok"; } elseif ($verification === 0) { echo "ng"; $error = openssl_error_string(); if ($error) { echo "error: " . $error . "\n"; } } elseif ($verification === -1) { echo "error: " . openssl_error_string() . "\n"; } else { echo "error\n"; } function der2pem($der_data) { $pem = chunk_split(base64_encode($der_data), 64, "\n"); $pem = "-----BEGIN PUBLIC KEY-----\n".$pem."-----END PUBLIC KEY-----\n"; return $pem; }
参考:https://pakapaka.jp/inapp-google-purchase/
phpで検証2
private function verifyGooglePlay($transaction){ $receipt = $transaction['receipt']; $signature = $transaction['signature']; // RSA public key generation $pubkey = openssl_get_publickey($this->pubkey); // Base64 decode signature $signature = base64_decode($signature); // Signature verification $result = (int)openssl_verify($receipt, $signature, $pubkey, OPENSSL_ALGO_SHA1); if($result !== 1){ Log::notice('Signature invalid.'); return false; } openssl_free_key($pubkey); // Check package name $receipt = json_decode($transaction['receipt']); if($receipt->packageName !== $this->bundle_id) { Log::notice('Invalid package id.'); return false; } return true; }
openssl_verifyで、OPENSSL_ALGO_SHA1を使っている。