使用passkit-generator生成无效.pkpass文件的问题求助
Apple Wallet Pass生成无效问题排查
问题背景
首次使用passkit-generator开发Apple Wallet功能,生成的.pkpass文件检测无效,发送至iPhone邮箱无法打开,但Apple官方示例通行证可正常使用,怀疑是证书问题,已排查数小时未解决。
代码实现
const fs = require("fs"); const { PKPass } = require("passkit-generator"); try { (async () => { const pass = await PKPass.from( { model: "./passes/sample", certificates: { wwdr: fs.readFileSync("./certificates/awdrca.pem"), signerCert: fs.readFileSync("./certificates/signerCert.pem"), signerKey: fs.readFileSync("./certificates/signerKey.pem"), signerKeyPassphrase: "[private passphrase]", }, }, { serialNumber: "[generated at random]", } ); pass.setBarcodes("36478105430"); // Random value const buffer = pass.getAsBuffer(); fs.writeFileSync("output/pass.pkpass", buffer); })(); } catch (err) { console.log(err); }
pass.json配置
{ "formatVersion": 1, "passTypeIdentifier": "[the pass type identifier]", "serialNumber": "8j23fm3", "webServiceURL": "https://example.com/passes/", // I don't entirely know what this is good for "authenticationToken": "[generated randomly]", "teamIdentifier": "[Apple dev team id]", "barcode": { "message": "123456789", "format": "PKBarcodeFormatPDF417", "messageEncoding": "iso-8859-1" }, "organizationName": "[Org name of our company]", "description": "Toy Town Membership", "logoText": "Toy Town", "foregroundColor": "rgb(255, 255, 255)", "backgroundColor": "rgb(197, 31, 31)", "generic": {[contents of the pass]} }
排查方向与解决方案
1. 证书链有效性检查
这是pass无效最常见的原因,重点核对以下几点:
- WWDR证书版本:确认使用的是Apple Worldwide Developer Relations G3 Certification Authority证书(旧版WWDR证书已过期),且为PEM格式。可通过
openssl x509 -in awdrca.pem -text -noout查看证书有效期和颁发机构。 - 签名证书与私钥匹配:
- 签名证书必须是Apple开发者后台针对你的
passTypeIdentifier生成并下载的证书,证书内容要包含正确的Pass Type ID权限。 - 私钥是生成CSR请求时本地导出的密钥,确保PEM格式正确,且
signerKeyPassphrase与私钥的加密密码完全一致。可通过openssl rsa -in signerKey.pem -check验证私钥有效性(输入密码后无报错则正常)。
- 签名证书必须是Apple开发者后台针对你的
- 证书格式正确性:所有证书文件不能有多余的空白行或格式错误,确保是纯PEM编码内容。
2. pass.json配置修正
- 占位符替换:
passTypeIdentifier:替换为开发者后台创建的完整Pass Type ID(如pass.com.yourcompany.ToyTownMembership),必须完全匹配,大小写敏感。teamIdentifier:替换为Apple开发者账号的Team ID(可在开发者后台"Account"页面查看)。generic字段:当前的{[contents of the pass]}是无效JSON占位符,必须替换为符合Pass格式的结构,比如:"generic": { "primaryFields": [ { "key": "memberLevel", "label": "会员等级", "value": "黄金会员" } ] }
- 可选字段移除:若不需要Pass更新功能,可以暂时删除
webServiceURL和authenticationToken字段,避免配置错误影响验证。 - serialNumber一致性:代码中通过参数覆盖了pass.json的serialNumber,确保生成的字符串唯一即可,无格式问题。
3. 代码与资源检查
- 资源文件完整性:
./passes/sample目录下必须包含所有要求的资源文件(如logo.png、icon.png、logo@2x.png等),尺寸符合Apple规范(logo建议160x50px,icon 29x29px),文件名无大小写错误(iOS文件系统区分大小写)。 - 条码配置冲突:pass.json中已配置
barcode字段,代码中又调用setBarcodes会覆盖原有配置,建议统一用一种方式配置,避免冲突。 - 错误日志完善:当前代码的错误捕获可能无法覆盖async函数内部的异常,建议修改为:
这样能捕获到更具体的错误信息(如证书加载失败、签名错误等)。(async () => { try { // 原有代码 } catch (innerErr) { console.error("生成Pass出错:", innerErr); } })();
4. 本地验证方法
- 把生成的
.pkpass文件改后缀为.zip并解压,检查是否存在manifest.json和signature文件;打开manifest.json确认所有资源文件的哈希值正确,无缺失条目。 - 用OpenSSL验证签名有效性:
如果验证通过会输出"Verification successful",否则会提示具体的签名错误,可直接定位证书链问题。openssl smime -verify -in signature -content manifest.json -inform der -CAfile ./certificates/awdrca.pem
内容的提问来源于stack exchange,提问作者Firippo
相关产品推荐
相关产品推荐

