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

如何使用Jose库验证Apple签名的JWS(x5c证书链)

正确的Apple Store Webhook签名验证流程(基于Jose库)

Apple Store Webhook(Notification API v2)的签名验证核心是确认JWS的合法性,同时验证附带的证书链完整可信。以下是针对你的场景的正确实现方案:

现有代码的问题

你当前的实现存在两个关键错误:

  • 证书不是JWT格式,不能用jwtVerify来验证证书间的签名关系
  • 缺少对JWS本身的签名验证,仅验证证书链无法确认请求内容未被篡改

完整验证代码

import { jwtVerify, importX509, verifyCertificateChain, decodeJwt } from 'jose';

async function verifyAppleWebhook(signedPayload, env) {
  try {
    // 1. 解码JWS获取header中的证书链
    const decodedJwt = decodeJwt(signedPayload);
    const x5cChain = decodedJwt.header.x5c;
    if (!x5cChain || x5cChain.length < 2) {
      throw new Error('Invalid certificate chain in JWS header');
    }

    // 2. 导入所有证书:叶证书(签名JWS的证书)、中间证书、本地根证书
    const leafCertificate = await importX509(x5cChain[0], 'ES256');
    const intermediateCertificate = await importX509(x5cChain[1], 'ES256');
    const rootCertificate = await importX509(env.APPLE_ROOT_CERTIFICATION, 'ES256');

    // 3. 验证证书链:叶证书由中间证书签名,中间证书由根证书签名
    await verifyCertificateChain(leafCertificate, [intermediateCertificate, rootCertificate]);

    // 4. 验证JWS本身的签名:确认请求内容是叶证书签署的
    const { payload } = await jwtVerify(signedPayload, leafCertificate, {
      issuer: 'https://appleid.apple.com', // Apple固定签发者
      audience: '你的应用Bundle ID' // 替换为你的App Bundle ID
    });

    // 5. 可选:验证叶证书的主题和有效期,提升安全性
    const leafCertInfo = leafCertificate.toJSON();
    const now = Math.floor(Date.now() / 1000);
    if (!leafCertInfo.subject.includes('Apple Push Notification service') || 
        leafCertInfo.notBefore > now || 
        leafCertInfo.notAfter < now) {
      throw new Error('Invalid leaf certificate');
    }

    return payload; // 验证通过,返回解析后的通知内容
  } catch (err) {
    console.error('Webhook verification failed:', err);
    return new Response('Failed to verify Apple webhook signature.', { status: 401 });
  }
}

关键注意事项

  • 算法固定:Apple Notification API v2仅使用ES256算法,不要更换其他算法
  • 证书导入方式:必须用importX509导入证书,x5c数组中的内容是完整X.509证书,不是SPKI格式公钥
  • JWT校验参数:issuer固定为https://appleid.apple.com,audience必须严格匹配你的应用Bundle ID,防止伪造请求
  • 链验证工具:Jose的verifyCertificateChain会自动完成证书链的层级签名验证,无需手动逐个校验

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 02:17:44