You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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验证私钥有效性(输入密码后无报错则正常)。
  • 证书格式正确性:所有证书文件不能有多余的空白行或格式错误,确保是纯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验证签名有效性:
    openssl smime -verify -in signature -content manifest.json -inform der -CAfile ./certificates/awdrca.pem
    
    如果验证通过会输出"Verification successful",否则会提示具体的签名错误,可直接定位证书链问题。

内容的提问来源于stack exchange,提问作者Firippo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 01:06:13