facebook twitter hatena line email

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

提供: 初心者エンジニアの簡易メモ
移動: 案内検索
(phpで検証)
(サーバのopenssl_verifyが動くか確認)
行48: 行48:
 
} elseif ($verification === 0) {
 
} elseif ($verification === 0) {
 
     echo "署名は無効です。\n";
 
     echo "署名は無効です。\n";
 +
} elseif ($verification === -1) {
 +
    echo "エラーが発生しました: " . openssl_error_string() . "\n";
 
} else {
 
} else {
 
     echo "エラーが発生しました。\n";
 
     echo "エラーが発生しました。\n";

2025年3月18日 (火) 16:21時点における版

サーバの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で検証

$receiptJson = '{"orderId":"GPA.xxxx-xxxx-xxxx-xxxxx","productId":"product1",...}';
$signature = base64_decode('[signatureデータ]');

// 下記のURLなどを参考にpem形式に変換
// FYI: http://php.net/manual/ja/ref.openssl.php
$publicKey = der2pem(base64_decode('[googleplay収益化セットアップのrsa公開鍵]'));

if (openssl_verify($receiptJson, $signature, openssl_get_publickey($publicKey)) === 1) {
    // 検証ok
}

参考: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を使っている。

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