如何用JavaScript从ASN.1解析Apple收据的bundle_id等信息?
Node.js 解析Apple App Store收据ASN.1格式提取核心字段
核心思路
Apple App Store收据在PKCS#7容器的EncapsulatedContentInfo中以OCTET STRING存储,解析需两步:先提取该OCTET STRING作为收据的ASN.1 payload,再解析payload内部结构——它是一个包含多组属性的序列,每组属性由类型码、版本、值组成,bundle_id、receipt_creation_date等字段对应固定类型码(比如bundle_id对应2,receipt_creation_date对应12)。
具体实现步骤(基于node-forge + asn1js)
解析PKCS#7容器,提取收据ASN.1 payload
用node-forge加载PKCS#7数据,定位并提取目标OCTET STRING:const forge = require('node-forge'); const asn1js = require('asn1js'); // receiptData为base64编码的收据字符串 function extractReceiptPayload(receiptData) { const derBuffer = forge.util.decode64(receiptData); const asnStructure = forge.asn1.fromDer(derBuffer); // 定位PKCS#7中的EncapsulatedContentInfo -> eContent const signedData = asnStructure.value[0].value[1]; const encapContentInfo = signedData.value[2]; const eContent = encapContentInfo.value[1].value[0]; // 转换为Uint8Array供asn1js解析 return new Uint8Array(forge.util.createBuffer(eContent.value).bytes()); }解析收据ASN.1 payload,提取目标字段
用asn1js解析payload,遍历属性序列匹配类型码提取字段:function parseReceiptFields(payload) { const asn1Result = asn1js.fromBER(payload); const receiptSequence = asn1Result.result.valueBlock.value; const receiptFields = {}; receiptSequence.forEach(attribute => { const typeId = attribute.valueBlock.value[0].valueBlock.valueDec; const value = attribute.valueBlock.value[2].valueBlock.value; switch (typeId) { case 2: // bundle_id receiptFields.bundle_id = value; break; case 12: // receipt_creation_date receiptFields.receipt_creation_date = new Date(value); break; // 可扩展其他字段:比如交易ID(17)、产品ID(19)、原始购买日期(14)等 } }); return receiptFields; }整合调用示例
const receiptData = '你的base64格式收据字符串'; const payload = extractReceiptPayload(receiptData); const parsedFields = parseReceiptFields(payload); console.log('Bundle ID:', parsedFields.bundle_id); console.log('收据创建时间:', parsedFields.receipt_creation_date);
关键说明
- 类型码对应关系:Apple官方定义了所有收据字段的类型码,可参考官方文档的「Receipt Attributes」部分。
- 日期处理:收据中的日期字段是IA5STRING格式的ISO 8601字符串,直接用
new Date()即可转换为JavaScript日期对象。 - 简化方案:若不想手动实现,可使用第三方封装库(如
app-store-receipt-parser),内部已完成PKCS#7解析和字段映射逻辑。
内容的提问来源于stack exchange,提问作者Juraj Zovinec
相关产品推荐
相关产品推荐

