Ошибка проверки подписи игрока в мгновенной игре Facebook

В настоящее время я разрабатываю мгновенную игру на Facebook, и мне нужно убедиться, что информация об игроке является подлинной из Facebook. Facebook обеспечивает проверку с помощью хешированной подписи, как описано здесь:

https://developers.facebook.com/docs/games/instant-games/sdk/fbinstant6.2#signedplayerinfo

Я выполнил шаги, как указано, но никогда не могу получить совпадающую подпись:

Это подпись:

$_POST['psig'] = 'je3yV8uKmysDrjXv1xp_RY2rTMJLEREM7xj8SGt5HEk.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImlzc3VlZF9hdCI6MTU1MjI1NTc2OCwicGxheWVyX2lkIjoiMjA1OTE4OTA2MDgyMzk4MyIsInJlcXVlc3RfcGF5bG9hZCI6InBkYXRhIn0';

1) Разделить подпись на две части, разделенные знаком «.». персонаж.

$first_part = explode('.', $_POST['psig'])[0];
echo $first_part;

// Output:
je3yV8uKmysDrjXv1xp_RY2rTMJLEREM7xj8SGt5HEk

$second_part = explode('.', $_POST['psig'])[1];
echo $second_part;

// Output
eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImlzc3VlZF9hdCI6MTU1MjI1NTc2OCwicGxheWVyX2lkIjoiMjA1OTE4OTA2MDgyMzk4MyIsInJlcXVlc3RfcGF5bG9hZCI6InBkYXRhIn0

2) Декодируйте первую часть (закодированную подпись) с помощью кодировки base64url.

echo base64_decode($first_part);

// Output:
���Wˊ�+�5��Qcj�0��DC;�?�G

3) Декодируйте вторую часть (полезную нагрузку ответа) с помощью кодировки base64url, которая должна быть строковым представлением объекта JSON со следующими полями: ** алгоритм — всегда равен HMAC-SHA256 ** issue_at — временная метка unix, когда этот ответ был выпущен. ** player_id - уникальный идентификатор игрока. ** request_payload — строка requestPayload, указанная вами при вызове FBInstant.player.getSignedPlayerInfoAsync.

$payload = base64_decode($second_part);
echo $payload;

// Output:
{"algorithm":"HMAC-SHA256","issued_at":1552255768,"player_id":"2059189060823983","request_payload":"pdata"}

4) Хэшируйте всю строку полезной нагрузки ответа, используя HMAC SHA-256 и секрет вашего приложения, и подтвердите, что она равна закодированной подписи.

$check = hash_hmac('sha256', $payload, 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', true);
echo $check;

// Output:
n4Q�Kމ`<�?�����tT�~x����L�

Я провел несколько часов с этим и не могу понять, что я делаю неправильно!


person Michael Samuel    schedule 11.03.2019    source источник


Ответы (1)


Наконец получил!

У меня было 2 ошибки:

1) При декодировании закодированной подписи для проверки следует использовать URL-адрес base64decode, а НЕ обычный base64decode. Таким образом, код на шаге 2 должен быть таким:

$first_part = base64_decode(str_replace(array('-', '_'), array('+', '/'), $first_part));

2) Сгенерированный хэш должен иметь ОРИГИНАЛЬНУЮ закодированную строку response payload, а НЕ декодированную. Док не очень ясно об этом. Так должно быть так:

$check = hash_hmac('sha256', $second_part, $app_secret, true);

Сделав вышеописанное, декодированная подпись будет равна двоичным данным в сгенерированном хэше :)

И, наконец, чтобы проверить, действительна ли подпись: if($first_part == $check){ //valid }

person Michael Samuel    schedule 11.03.2019