使用PHP验证windows 8购买(收据)

使用PHP验证windows 8购买(收据),php,windows-8,in-app-purchase,signedxml,xmlseclibs,Php,Windows 8,In App Purchase,Signedxml,Xmlseclibs,我需要使用PHP验证在Windows 8应用程序服务器端进行的应用内购买。MSDN仅在C#中有一个示例。现在我已经花了一整天的时间在寻找用PHP实现的方法。没有成功。在互联网上,关于这个话题的例子只有.NET 我发现了一些关于签名XML和x509的部分信息,以及一些库(xmlseclibs-无用,使用了不支持sha256的openssl_*函数;phpseclib-看起来很有希望,但它们的文档和示例很差,没有帮助) 有没有可能在不了解签名XML、RSA和x509的所有知识的情况下以某种方式做到这

我需要使用PHP验证在Windows 8应用程序服务器端进行的应用内购买。MSDN仅在C#中有一个示例。现在我已经花了一整天的时间在寻找用PHP实现的方法。没有成功。在互联网上,关于这个话题的例子只有.NET

我发现了一些关于签名XML和x509的部分信息,以及一些库(xmlseclibs-无用,使用了不支持sha256的openssl_*函数;phpseclib-看起来很有希望,但它们的文档和示例很差,没有帮助)


有没有可能在不了解签名XML、RSA和x509的所有知识的情况下以某种方式做到这一点?现在我读了几乎所有的东西,但到处都是关于编码的信息。没有关于验证的内容。

请自己说。我喜欢phpseclib的“构建您自己的示例”文档方法


也就是说,我不认为phpseclib真的可以用于这种情况。所以你有SignatureValue标签。那个签名包括什么?对于XML签名,我的理解是签名涵盖了XML的规范化形式。xmlseclibsnromalize一个XML文档,但phpseclib没有,因为它是一个加密库,而不是一个XML库。

我使用库验证了WP8 IAP收据

此外,还需要启用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
}
do{
$doc=新的DOMDocument();
$xml=$\u POST['receipt\u data'];//此处是您的收据xml!
//去除不需要的字符-重要!!!
$xml=str_replace(数组(“\n”、“\t”、“\r”)、“,$xml);
//一些收据(可能大部分是WP8)有不必要的空格,而不是制表符
$xml=preg_replace('/\s+/','',$xml);

$xml=str_replace(“>请不要误解我的意思,我不是故意粗鲁,phpseclib看起来像一个强大的库。但是我错过了更多详细的例子,比如在$x509->loadCA(“…”)中加载什么。我想用它通过MS文档中编写的证书来验证xml签名。而且验证应该是可能的(某种程度上)通过这个库。我找到了这个示例,但我不确定使用什么进行验证。我认为期望phpseclib讨论如何针对其他X.509实现对其进行验证是不合理的。phpseclib的网站应该记录phpseclib,而不是其他软件包。这意味着它确实提供了一个互操作性页面,可以为您的应用程序提供服务目的:你让它工作了吗?