PHP版本Google廣告admob服務端回調驗證SSV

老文章,搬運到這裏而已。php

因業務須要接入Google的激勵廣告,涉及Google回調的服務器端驗證 (SSV) server side verifiy。
Python版本的基於第三方包ecdsa開箱即用,PHP版本也有一個ecdsa庫,可是過於複雜。
想到以前作支付寶支付,google支付的openssl rsa密鑰簽名校驗。仍是本身來寫個簡單實用的。git

Google公鑰的地址:

https://www.gstatic.com/admob/reward/verifier-keys.jsongithub

注意:shell

  1. AdMob 密鑰服務器提供的公鑰會不按期輪換。爲確保能夠繼續按預期驗證 SSV 回調,請勿使公鑰的緩存時間超過 24 小時。
  2. Google 預計您的服務器會針對 SSV 回調返回 HTTP 200 OK 成功狀態響應代碼。若是您的服務器沒法訪問或未提供預期的響應,Google 將從新嘗試發送 SSV 回調,每隔 1 秒發送最多 5 次。
  3. 用回調參數中key_id 取對應公鑰,進行簽名驗證。

獲取公鑰能夠使用curl 或 file_get_contents 函數,推薦使用curl。 這裏就再也不寫獲取公鑰的代碼了,直接copy過來使用。json

完整代碼以下:數組

// Google admob 公鑰
$verifier_keys = '{"keys":[{"keyId":3335741209,"pem":"-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE+nzvoGqvDeB9+SzE6igTl7TyK4JB\nbglwir9oTcQta8NuG26ZpZFxt+F2NDk7asTE6/2Yc8i1ATcGIqtuS5hv0Q==\n-----END PUBLIC KEY-----","base64":"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE+nzvoGqvDeB9+SzE6igTl7TyK4JBbglwir9oTcQta8NuG26ZpZFxt+F2NDk7asTE6/2Yc8i1ATcGIqtuS5hv0Q=="}]}';

// Google 回調參數字符串,get傳參
$query_string = '';

// json 格式公鑰字符串,轉數組,根據回調參數query_string中的key_id 取對應的公鑰驗證簽名
$verifier_keys_arr = json_decode($verifier_keys, true);
if(empty($verifier_keys_arr) || !is_array($verifier_keys_arr)){
    throw new Exception("wrong google public keys!");
}
// 公鑰的兩種格式,pem 和 base64 
$publicKey_pem = $verifier_keys_arr['keys'][0]['pem'];
$publicKey_base64 = $verifier_keys_arr['keys'][0]['base64'];
// base64 的格式化
$publicKeyString = "-----BEGIN PUBLIC KEY-----\n" . wordwrap($publicKey_base64, 64, "\n", true) . "\n-----END PUBLIC KEY-----";
// pem轉公鑰資源對象
$publicKey = openssl_pkey_get_public($publicKeyString);
// 注: publicKey_pem, publicKeyString, publicKey 都是能夠正常簽名的

// 解析回調參數
parse_str($query_string, $query_arr);
// 簽名結果字符串
$signature = trim($query_arr['signature']);
// 重要的是這裏的簽名結果字符串的替換 和 補位
$signature = str_replace(['-', '_'], ['+', '/'], $signature);
$signature .= '===';

// 進行簽名的數據元字符串
$message = substr($query_string, 0, strpos($query_string, 'signature')-1);

$return = [
    'code' => 0,
    'message' => 'error'
];

//驗證簽名, 這裏使用 $publicKey,$publicKey_pem, $publicKeyString 都是能夠的
$success = openssl_verify($message, base64_decode($signature), $publicKey, OPENSSL_ALGO_SHA256);
if ($success === -1) {
    $return['message'] = '111111'.openssl_error_string();
} elseif ($success === 1) {
    $return['code'] = 1;
    $return['message'] = 'success';
} else {
    $return['message'] = '222222'.openssl_error_string();
}

var_dump($return);

執行php腳本:

$ php -f admob_ssv.php
array(2) {
  'code' =>
  int(1)
  'message' =>
  string(7) "success"
}

success 爲校驗成功。緩存

附:
composer包:composer require depakin/admobssv
github地址:https://github.com/yisangwu/google_admob_ssv服務器

相關文章
相關標籤/搜索