首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用PHP验证windows 8购买(收据)

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

Stack Overflow用户
提问于 2012-12-03 01:58:34
回答 2查看 1.3K关注 0票数 5

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

我找到了一些关于签名XML和x509的部分信息,还有一些库(xmlseclibs无用,使用不支持sha256的openssl_*函数;phpseclib -看起来很有前途,但他们的文档和示例很糟糕,没有帮助)。

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-06-23 22:21:43

我设法使用xmlseclibs库验证了WP8 IAP收据。

此外,您还需要启用php curl。

代码语言:javascript
复制
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
}
票数 1
EN

Stack Overflow用户

发布于 2012-12-04 06:37:44

为你自己说话吧。我喜欢phpseclib的“构建自己的示例”的文档方法。

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

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13672076

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档