苹果网站推送:推送包签名验证失败


Apple website push: Signature verification of push package failed

根据Apple网站推送通知指南,我收到了一篇返回/endpoint/v1/log的帖子,并出现以下错误:Signature verification of push package failed.

然而,当我使用手动下载和验证时

curl -O $endpoint/push/v1/pushPackages/x/y
unzip y
openssl smime -verify -in signature -inform der -content manifest.json -noverify

我得到Verification successful

证书被正确地添加到Apple Developer控制台下,ZIP的生成非常直接:

$z = new ZipArchive();
$z->open($tmp, ZIPARCHIVE::CREATE);
$manifest = [];
$data = json_encode([
    'websiteName' => $name,
    'websitePushId' => $pushId,
    'allowedDomains' => $domains,
    'webServiceURL' => "$endpoint/push"
]);
$manifest['website.json'] = sha1($data);
$z->addFromString('website.json', $data);
$data = file_get_contents('static/favicon.png');
foreach (['16x16','16x16@2x','32x32','32x32@2x','128x128','128x128@2x'] as $f) {
    $f = 'icon.iconset/icon_'.$f.'.png';
    $manifest[$f] = sha1($data);
    $z->addFromString($f, $data);
}
file_put_contents('/tmp/manifest.json', json_encode($manifest));
$z->addFile('/tmp/manifest.json','manifest.json');
$pem = file_get_contents('etc/aweb.pem');
$cert = openssl_x509_read($pem);
$pk = openssl_pkey_get_private($pem, 'developer');
openssl_pkcs7_sign(
    '/tmp/manifest.json', '/tmp/signature',
    $cert, $pk, array(), PKCS7_BINARY | PKCS7_DETACHED
);
// PEM to DER
$pem = file_get_contents('/tmp/signature');
preg_match('~Content-Disposition:[^'n]+'s*?([A-Za-z0-9+=/'r'n]+)'s*?-----~', $pem, $matches);
$data = base64_decode($matches[1]);
$z->addFromString('signature', $data);
$z->close();

注意-noverify的使用,因为尽管进行了尝试,我还是无法正确设置证书链:

curl -L https://www.apple.com/appleca/AppleIncRootCertificate.cer | openssl x509 -inform der > certs.pem
curl -L http://developer.apple.com/certificationauthority/AppleWWDRCA.cer | openssl x509 -inform der >> certs.pem
openssl smime -verify -in signature -inform der -content manifest.json -CAfile certs.pem

产生

Verification failure
140184513181352:error:21075075:PKCS7 routines:PKCS7_verify:certificate verify error:pk7_smime.c:342:Verify error:unsupported certificate purpose

另外一点:我发现文档中非常不清楚ZIP文件是否应该包含根目录(如果应该,它应该命名为什么)。经过几个小时的Missing files错误,我终于认为ZIP应该而不是包含根目录。

我已经设法找到了问题:window.safari.pushNotification.requestPermission的(第二个)pushId参数包含拼写错误,并且与manifest.json中的网站pushId不匹配。

结论:Safari方面令人难以置信的误导性错误报告;)。