Мне нужно проверить покупки в приложении, сделанные в приложениях Windows 8 на стороне сервера, используя PHP. На странице документации MSDN приведен пример только на C #. Прямо сейчас я провел целый день, ища способ сделать это на PHP. Нет успеха. По всему Интернету есть только примеры .NET на эту тему.
Я нашел некоторую частичную информацию о подписанных XML и x509, некоторые библиотеки (xmlseclibs – бесполезно, использует функции openssl_ *, которые не поддерживают sha256; phpseclib – выглядит многообещающе, но их документация и примеры плохие, без помощи).
Возможно ли это сделать так или иначе, не изучая все о подписанных XML, RSA и x509? Сейчас я читал почти все, но везде есть информация только о кодировании. Ничего о проверке.
Мне удалось проверить получение WPA IAP с помощью библиотеки xmlseclibs .
Кроме того, вам нужно включить php curl.
do { $doc = new DOMDocument(); $xml = $_POST['receipt_data']; // your receipt xml here! // strip unwanted chars - IMPORTANT!!! $xml = str_replace(array("\n","\t", "\r"), "", $xml); //some (probably mostly WP8) receipts have unnecessary spaces instead of tabs $xml = preg_replace('/\s+/', " ", $xml); $xml = str_replace("> <", "><", $xml); $doc->loadXML($xml); $receipt = $doc->getElementsByTagName('Receipt')->item(0); $certificateId = $receipt->getAttribute('CertificateId'); $ch = curl_init("https://lic.apps.microsoft.com/licensing/certificateserver/?cid=$certificateId"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); $publicKey = curl_exec($ch); $errno = curl_errno($ch); $errmsg = curl_error($ch); curl_close($ch); if ($errno != 0) { $verifyFailed = true; break; } // Verify xml signature require('./xmlseclibs.php'); $objXMLSecDSig = new XMLSecurityDSig(); $objDSig = $objXMLSecDSig->locateSignature($doc); if (!$objDSig) { $verifyFailed = true; break; } try { $objXMLSecDSig->canonicalizeSignedInfo(); $retVal = $objXMLSecDSig->validateReference(); if (!$retVal) { throw new Exception("Error Processing Request", 1); } $objKey = $objXMLSecDSig->locateKey(); if (!$objKey) { throw new Exception("Error Processing Request", 1); } $key = NULL; $objKeyInfo = XMLSecEnc::staticLocateKeyInfo($objKey, $objDSig); if (! $objKeyInfo->key && empty($key)) { $objKey->loadKey($publicKey); } if (!$objXMLSecDSig->verify($objKey)) { throw new Exception("Error Processing Request", 1); } } catch (Exception $e) { $verifyFailed = true; break; } $productReceipt = $doc->getElementsByTagName('ProductReceipt')->item(0); $prodictId = $productReceipt->getAttribute('ProductId'); $purchaseDate = $productReceipt->getAttribute('PurchaseDate'); } while(0); if ($verifyFailed) { // invalid receipt } else { // valid receipt }
Говори за себя. Мне нравится подход phpseclib «постройте свой собственный пример» в документации.
Тем не менее, я не думаю, что phpseclib действительно может быть использован в этом случае. Таким образом, у вас есть тег SignatureValue. Что покрывает эта подпись? С XML-подписями я понимаю, что подпись охватывает нормализованную форму XML. xmlseclibsnormalizes XML doc, но phpseclib не так, как это crypto lib – не XML lib.