facebook twitter hatena line email

「Unity/課金/リモートレシート検証/phpサーバ」の版間の差分

提供: 初心者エンジニアの簡易メモ
移動: 案内検索
(phpで検証)
(Android側=)
 
(同じ利用者による、間の15版が非表示)
行1: 行1:
 
==サーバのsslが有効になってるか確認==
 
==サーバのsslが有効になってるか確認==
 
<pre>
 
<pre>
 +
$ openssl version
 +
OpenSSL 1.1.1t  7 Feb 2023
 +
</pre>
 +
 +
==サーバのsha1が有効になってるか確認==
 +
===redhat系===
 +
<pre>
 +
$ update-crypto-policies --show
 +
DEFAULT-SHA1
 +
</pre>
 +
 +
==サーバのsslがphpで有効になってるか確認==
 +
<pre>
 +
<?php
 
if (extension_loaded('openssl')) {
 
if (extension_loaded('openssl')) {
 
     echo "OpenSSLは有効になっています。\n";
 
     echo "OpenSSLは有効になっています。\n";
行8: 行22:
 
}
 
}
 
</pre>
 
</pre>
OpenSSLは有効になっています。OpenSSL バージョン:OpenSSL 3.0.7 1 Nov 2022
+
OpenSSLは有効になっています。
==サーバのopenssl_verifyが動くか確認==
+
OpenSSL バージョン: OpenSSL 1.1.1t  7 Feb 2023
 +
 
 +
==サーバのsslのsha1がphpで有効になってるか確認==
 +
<pre>
 +
<?php
 +
$algorithms = openssl_get_md_methods();
 +
$algorithms_lower = array_map('strtolower', $algorithms); // すべて小文字に変換
 +
if (in_array('sha1', $algorithms_lower)) {
 +
    echo "SHA1 is supported by OpenSSL in PHP\n";
 +
} else {
 +
    echo "SHA1 is NOT supported by OpenSSL in PHP\n";
 +
}
 +
</pre>
 +
 
 +
==サーバのphpのopenssl_verify()関数が動くか確認==
 
<pre>
 
<pre>
 
$ cd /tmp/
 
$ cd /tmp/
行61: 行89:
 
</pre>
 
</pre>
  
==phpで検証==
+
==phpで署名検証==
 
<pre>
 
<pre>
 
<?php
 
<?php
行101: 行129:
 
参考:https://pakapaka.jp/inapp-google-purchase/
 
参考:https://pakapaka.jp/inapp-google-purchase/
  
==phpで検証2==
+
参考:https://qiita.com/danishi/items/4eeca49e03a3c723673f
<pre>
+
private function verifyGooglePlay($transaction){
+
$receipt = $transaction['receipt'];
+
$signature = $transaction['signature'];
+
  
// RSA public key generation
+
==phpで、レポートAPIへアクセス==
$pubkey = openssl_get_publickey($this->pubkey);
+
===Android側===
  
// Base64 decode signature
+
[[Php/GooglePlayApi]] [ショートカット]
$signature = base64_decode($signature);
+
  
// Signature verification
+
===iOS側===
$result = (int)openssl_verify($receipt, $signature, $pubkey, OPENSSL_ALGO_SHA1);
+
<pre>
if($result !== 1){
+
本番
Log::notice('Signature invalid.');
+
https://buy.itunes.apple.com/verifyReceipt
return false;
+
}
+
openssl_free_key($pubkey);
+
  
// Check package name
+
サンドボックス(本番以外)
$receipt = json_decode($transaction['receipt']);
+
https://sandbox.itunes.apple.com/verifyReceipt
if($receipt->packageName !== $this->bundle_id) {
+
Log::notice('Invalid package id.');
+
return false;
+
}
+
return true;
+
}
+
 
</pre>
 
</pre>
openssl_verifyで、OPENSSL_ALGO_SHA1を使っている。
+
参考:https://spirits.appirits.com/role/engineer/21876/
 
+
参考:https://qiita.com/danishi/items/4eeca49e03a3c723673f
+

2025年3月31日 (月) 18:40時点における最新版

サーバのsslが有効になってるか確認

$ openssl version
OpenSSL 1.1.1t  7 Feb 2023

サーバのsha1が有効になってるか確認

redhat系

$ update-crypto-policies --show
DEFAULT-SHA1

サーバのsslがphpで有効になってるか確認

<?php
if (extension_loaded('openssl')) {
    echo "OpenSSLは有効になっています。\n";
    echo "OpenSSL バージョン: " . OPENSSL_VERSION_TEXT . "\n";
} else {
    echo "OpenSSLは無効になっています。\n";
}

OpenSSLは有効になっています。 OpenSSL バージョン: OpenSSL 1.1.1t 7 Feb 2023

サーバのsslのsha1がphpで有効になってるか確認

<?php
$algorithms = openssl_get_md_methods();
$algorithms_lower = array_map('strtolower', $algorithms); // すべて小文字に変換
if (in_array('sha1', $algorithms_lower)) {
    echo "SHA1 is supported by OpenSSL in PHP\n";
} else {
    echo "SHA1 is NOT supported by OpenSSL in PHP\n";
}

サーバのphpの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"","packageName":"jp.co.domain1.app1","productId":"product1","purchaseTime":1742311111111,"purchaseState":0,"purchaseToken":"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx","quantity":1,"acknowledged":false}';

$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_ALGO_SHA1);
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/

参考:https://qiita.com/danishi/items/4eeca49e03a3c723673f

phpで、レポートAPIへアクセス

Android側

Php/GooglePlayApi [ショートカット]

iOS側

本番
https://buy.itunes.apple.com/verifyReceipt

サンドボックス(本番以外)
https://sandbox.itunes.apple.com/verifyReceipt

参考:https://spirits.appirits.com/role/engineer/21876/