生成Safari推送包使用新中间证书出现签名验证错误求助
Safari推送包使用新AppleWWDRCAG3中间证书时签名验证失败
我一直在使用苹果《Configuring Safari Push Notifications》指南中提供的createPushPackage.php脚本来生成并签名我的推送包(为适配中间证书做了少量修改)。使用2023年2月到期的旧AppleWWDRCA中间证书时运行完全正常,但当我尝试使用2030年到期的新AppleWWDRCAG3中间证书时,用户尝试订阅时总会通过webhook返回{"logs":["Signature verification of push package failed"]}错误。
我使用的修改版createPushPackage.php脚本可在gist查阅。
我尝试使用对应的Ruby库生成推送包压缩包和签名时也出现了完全相同的问题:使用旧中间证书运行正常,使用新证书就报同样的错误。
请问是什么原因导致该问题?应该如何修复?
补充说明
我发现最新版苹果官方PHP脚本完全没有用到中间证书!我一开始以为这是疏漏,但实际测试后发现所有功能都运行正常。不过我担心该方案是否能长期适配,因为苹果官方指南明确要求需要使用中间证书签名。也有可能现在从苹果开发者中心下载的证书已经自带了中间证书?有没有人能提供对应的校验命令?
问题原因
- 证书链信任锚不匹配:旧版AppleWWDRCA(G1)由Apple Root CA签发,新版AppleWWDRCAG3由Apple Root CA - G3 Root签发,旧脚本仅附加中间证书未适配根证书信任链路,Safari校验时无法找到对应信任锚就会抛出验证失败错误。
- 证书拼接顺序错误:正确的PKCS7签名链顺序应为「站点推送证书」在前,「WWDR中间证书」在后,多数旧版自定义脚本把顺序写反,旧G1证书因Safari本地缓存了完整证书链未触发报错,新G3证书无对应缓存就会校验失败。
- 新的开发者证书已内置完整链:现在从苹果开发者中心下载的Safari推送证书p12文件,导出时默认已经包含了对应的中间证书和根证书信任链,不需要额外拼接中间证书,这也是新版官方脚本去掉中间证书参数仍能正常运行的原因。
修复方案
- 优先使用苹果官方最新版createPushPackage.php脚本,无需额外配置中间证书。该脚本是苹果官方针对新证书规则更新的版本,长期兼容性有官方保障,你实际测试也验证了可用性,无需担心适配问题。
- 如果你需要保留自定义中间证书的逻辑,调整证书拼接顺序,先加载站点推送证书,再追加G3中间证书,同时确认使用的G3中间证书是苹果官方发布的正确版本。
证书校验命令
你可以通过openssl命令验证你的证书文件是否已内置完整证书链:
# 替换为你的p12证书文件名,按提示输入证书密码即可查看完整证书信息 openssl pkcs12 -in your_push_cert.p12 -nokeys | openssl x509 -noout -text
校验生成的推送包签名是否合法:
# 解压pushPackage.zip后进入对应目录执行 openssl smime -verify -in signature -content manifest.json -inform der -noverify
命令返回Verification successful即代表签名本身合法,否则说明签名链存在错误。
内容的提问来源于stack exchange,提问作者Mohamed Hafez
相关产品推荐
相关产品推荐

