Safari推送包:如何修复Apple过期的WWDR证书



嗯,我们都知道,这即将发生,根据苹果的新闻稿,苹果WWDR证书在情人节到期(这就是我所说的"开发者之爱")。

我正在使用 C# 为 Safari 生成推送包,令人惊讶的是,这不再有效了。这是我在日志记录终端节点中收到的消息:

{"日志":["推送包的签名验证失败"]}

这是我旧的 PKCS#7 签名代码的样子:

//  Sign the message with the private key of the signer.
static byte[] PKCS7SignMessage(byte[] message, X509Certificate2 signerCertificate)
{
    //  Place message in a ContentInfo object.
    //  This is required to build a SignedCms object.
    ContentInfo contentInfo = new ContentInfo(message);
    //  Instantiate SignedCms object with the ContentInfo above.
    //  Has default SubjectIdentifierType IssuerAndSerialNumber.
    //  Has default Detached property value false, so message is
    //  included in the encoded SignedCms.
    SignedCms signedCms = new SignedCms(contentInfo, true);
    //  Formulate a CmsSigner object for the signer.
    CmsSigner cmsSigner = new CmsSigner(signerCertificate);
    cmsSigner.IncludeOption = X509IncludeOption.EndCertOnly;        
    //  Sign the CMS/PKCS #7 message.
    signedCms.ComputeSignature(cmsSigner);
    //  Encode the CMS/PKCS #7 message.
    return signedCms.Encode();
}

Apple 还要求"将路径传递给额外证书参数的更新中间"。

所以我试了这个:

X509Certificate2 appleIntermediate = new X509Certificate2();
appleIntermediate.Import(@"Path-to-new-WWRD.cer");
cmsSigner.Certificates.Add(appleIntermediate);

它没有用。 (推送包签名校验失败)

后来我试图改变这一行:

cmsSigner.IncludeOption = X509IncludeOption.WholeChain;

它没有用。我有一个例外说:

"无法将证书链构建到受信任的根颁发机构"。

好吧,现在我决定:

  • 将所有 Apple CA 根证书添加到本地计算机的受信任证书存储中。
  • 将续订的 WWRD 证书添加到本地计算机的中间证书存储中。
  • 重新启动该过程,然后重试代码。好消息是,它现在再次签名,理论上包括整个证书链。

但是:它没有用。 (推送包签名验证失败)

根据苹果公司的说法,解决这个问题是小菜一碟:

野生动物园推送通知

2016 年 2 月 14 日之前更新通知包签名服务器以包含 Web 推送证书和续订的中间证书。在此日期之后,在您的服务器更新之前,新用户将无法注册来自您网站的推送通知。如果使用 openssl_pkcs7_sign 函数仅使用 Web 推送证书对推送包进行签名,则应将路径传递给额外证书参数的续订中间。

现在,这在计划英语中意味着什么?如何将其应用于 C# 上下文?

苹果不想要整个链条。他们只希望包含您的证书及其中间证书。所以你的代码应该看起来像这样:

    static public byte[] PKCS7SignMessage(byte[] manifest_data, X509Certificate2 signerCertificate) {
        X509Certificate2Collection ca_chain;
        ContentInfo content;
        SignedCms signed_cms;
        CmsSigner signer;
        signed_cms = new SignedCms();
        ca_chain = new X509Certificate2Collection(new X509Certificate2(@"Path-to-new-intermediate-WWRD.cer"));
        content = new ContentInfo(manifest_data);
        signed_cms = new SignedCms(content, true);
        signer = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber, signerCertificate);
        signer.IncludeOption = X509IncludeOption.ExcludeRoot;
        signer.Certificates.AddRange(ca_chain);
        signed_cms.ComputeSignature(signer);
        return signed_cms.Encode();
    }

最新更新