如何创建签名文件以从 nodejs 服务器在 safari 中发送网络推送通知

How create signature file to sent web push notification in safari from nodejs server

现在我有一个服务器可以向 chrome 发送推送通知,我也想在 apple doc (https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/NotificationProgrammingGuideForWebsites/PushNotifications/PushNotifications.html) 中扩展 safari,但我不知道如何制作签名文件nodeJS

The Signature

The signature is a PKCS #7 detached signature of the manifest file. Sign the manifest file with the private key associated with your web push certificate that you obtained while registering with Apple. In PHP, you can do this with the openssl_pkcs7_sign function. The create_signature function in the attached createPushPackage.php companion file (the link is near the top of the page) shows how you can do this.

If the contents of your push package ever change, you’ll need to recompute your signature.

苹果在同一页中放了一个例子php:

// Creates a signature of the manifest using the push notification certificate.
function create_signature($package_dir, $cert_path, $cert_password) {
    // Load the push notification certificate
    $pkcs12 = file_get_contents($cert_path);
    $certs = array();
    if(!openssl_pkcs12_read($pkcs12, $certs, $cert_password)) {
        return;
    }

    $signature_path = "$package_dir/signature";

    // Sign the manifest.json file with the private key from the certificate
    $cert_data = openssl_x509_read($certs['cert']);
    $private_key = openssl_pkey_get_private($certs['pkey'], $cert_password);
    openssl_pkcs7_sign("$package_dir/manifest.json", $signature_path, $cert_data, $private_key, array(), PKCS7_BINARY | PKCS7_DETACHED);

    // Convert the signature from PEM to DER
    $signature_pem = file_get_contents($signature_path);
    $matches = array();
    if (!preg_match('~Content-Disposition:[^\n]+\s*?([A-Za-z0-9+=/\r\n]+)\s*?-----~', $signature_pem, $matches)) {
        return;
    }
    $signature_der = base64_decode($matches[1]);
    file_put_contents($signature_path, $signature_der);
}

有人知道如何在 nodeJS 中实现相同的功能吗?

好的,我终于找到了如何做到这一点,您必须先将证书和密钥转换为 PEM 格式

$ openssl x509 -in cert.cer -inform DER -outform PEM -out cert.pem
$ openssl pkcs12 -in key.p12 -out key.pem -nodes

之后,您可以使用 smime 模块签署您的清单(我使用 https://github.com/hipush/smime),我们准备好了,我们有一个签名:) :) :)