我问这个问题是为了分享解决方案代码。
背景: Apple 在 iOS 7 中引入了 AppReceipt。它也适用于 OS X IAP。此收据是一个 PKCS#7 容器 (asn.1),其有效负载也是 asn.1 结构。
Apple 的文档说明了如何控制设备上收据的有效性并对其进行解析以检查是否已为当前设备发出。
也有说明通过联系 Apple 服务器通过应用程序服务器验证收据。但是,在后一种情况下,Apple 返回的 json 数据不包括识别原始设备的信息。以前带有 transactionReceipt 的 IAP 协议(protocol)模型在 json 中包含 identifierForVendor UID。
问题:如何在服务器上解析二进制收据,使用 PHP,检查 UID 哈希,以确保该收据属于该设备?这可以在将收据发送到 Apple 服务器之前或之后完成。
Best Answer-推荐答案 strong>
这个脚本只检查哈希而不是整个收据签名的有效性。这项工作留给 Apple,通过向他们发送记录的收据。
哈希检查直接改编自 Apple 记录的 C 示例代码。这里的棘手任务是从二进制收据中找到正确的信息。
此代码使用 an ASN1 parser by Kris Bailey ,链接也在源代码中。
您需要更改解析器脚本代码中的一条注释:注释行#189 和取消注释#190。解析器脚本中的最后一个函数也未使用,可以删除。
<?php
//$vendID should be a binary string. If you have the vendorID as an ASCII string, convert it back
// $vendID = hex2bin(str_replace('-', '', $vendID_string)); //PHP 5.4+
$vendID = hextobin(str_replace('-', '', $vendID_string)); //PHP 5.3- function below
require_once 'ans1.php'; //donwnload from http://www.phpkode.com/source/s/mistpark-server/library/asn1.php
$asn_parser = new ASN_BASE;
//parse the receipt binary string
$pkcs7 = $asn_parser->parseASNString($receipt->bin);
// $asn_parser->printASN($pkcs7); //uncomment this line to print and inspect PKCS7 container
//target the payload object inside the container
$payload_sequence = $pkcs7[0]->asnData[1]->asnData[0]->asnData[2]->asnData;
//control the OID of payload
if ($payload_sequence[0]->asnData != '1.2.840.113549.1.7.1') {
echo "invalide payload OID";
exit;
}
//the payload octet_string is itself an ASN1 structure. Parse it.
$payload = $asn_parser->parseASNString($payload_sequence[1]->asnData[0]->asnData);
// $asn_parser->printASN($payload); //uncomment this line to print and inspect payload ASN structure
$payload_attributes = $payload[0]->asnData; //array of ASN_SEQUENCE
foreach ($payload_attributes as $attr) {
$type = $attr->asnData[0]->asnData;
switch ($type) {
case 2:
$bundle_id = $attr->asnData[2]->asnData;
break;
// case 3:
// $bundle_version = $attr->asnData[2]->asnData;
// break;
case 4:
$opaque = $attr->asnData[2]->asnData;
break;
case 5:
$hash = $attr->asnData[2]->asnData;
break;
default:
break;
}
}
//compute the hash
$hash_loc = sha1($vendID . $opaque . $bundle_id, true);
//control hash equality
if ($hash_loc == $hash) {
echo "OK\n";
}
else {
echo "KO\n";
}
echo "</pre>\n";
//*******************************************************
function hextobin($hexstr) {
$n = strlen($hexstr);
$sbin = '';
for ($i = 0; $i < $n; $i += 2) $sbin .= pack("H*", substr($hexstr,$i,2));
return $sbin;
}
?>
关于php - 如何在 PHP 中检查 Apple AppReceipt 服务器端的 UID 哈希?,我们在Stack Overflow上找到一个类似的问题:
https://stackoverflow.com/questions/24295195/
|