验证窗口8购买(收据)使用PHP(Verifying windows 8 purchases (re

2019-07-04 09:24发布

我需要验证使用PHP在Windows 8应用程序的服务器端做出应用内购买。 MSDN的文档页面只有在C#中的例子。 现在我已经寻找一种方式来做到这一点在PHP中度过了一整天。 没有成功。 所有在互联网上有关于这个主题只有.NET的例子。

我发现关于签署XML和X509的一些部分信息,一些库(xmlseclibs - 没用,使用openssl_ *功能不支持SHA256; phpseclib - 看起来很有希望,但他们的文档和例子是穷人没有帮助)。

是否有可能做到这一点不知何故没有了解签名的XML,RSA和X509的一切吗? 现在我读过几乎一切,但处处是只有编码信息。 一无所知验证。

Answer 1:

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

另外,你需要支持PHP卷曲。

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
}


Answer 2:

也就是你。 我爱phpseclib的“建立自己的例子”的方式进行的文档。

这就是说,我不认为phpseclib真的可以在这种情况下使用。 所以,你必须在标签的SignatureValue。 这是什么签名虽然覆盖? 随着XML签名,我的理解是,签名涵盖了XML的标准化形式。 xmlseclibsnormalizes一个XML文档,但phpseclib并不因为它是一个加密的lib - 不是一个XML库。



文章来源: Verifying windows 8 purchases (receipts) using PHP