【问题标题】:Apple pushes not working after upgrading from Java 6 to Java 7/8从 Java 6 升级到 Java 7/8 后,Apple 推送无法正常工作
【发布时间】:2016-05-19 15:19:01
【问题描述】:

我正在将通过 APNS 向 Apple 设备发送推送通知的应用程序从 Java 6 升级到 Java 8。

当使用相同的 PKCS12 证书文件在 Java 8 上运行在 Java 6 下工作的相同 JAR 时,如果我尝试发送推送,我会返回状态代码 8(无效令牌)。

这可能是什么原因造成的?

【问题讨论】:

    标签: java ios push-notification apple-push-notifications


    【解决方案1】:

    此问题是由 PKCS12 文件的内容和 Java 将 PKCS12 文件读取到 Java 6 和 7 之间的KeyStore 对象的方式发生变化共同引起的。

    在有问题的 pkcs12 文件上运行 openssl pkcs12 -in filename 会产生以下结果:

    Enter Import Password:
    MAC verified OK
    Bag Attributes
        friendlyName: Apple Development IOS Push Services: app.id.1
        localKeyID: .... snip ....
    subject=/UID=app.id.1/CN=Apple Development IOS Push Services: app.id.1/OU=PRXXXXXXXX/C=US
    issuer=/C=US/O=Apple Inc./OU=Apple Worldwide Developer Relations/CN=Apple Worldwide Developer Relations Certification Authority
    -----BEGIN CERTIFICATE-----
    ... snip ...
    -----END CERTIFICATE-----
    Bag Attributes
        friendlyName: Apple Development IOS Push Services: app.id.2
        localKeyID: .... snip ....
    subject=/UID=app.id.2/CN=Apple Development IOS Push Services: app.id.2/OU=PRXXXXXXXX/C=US
    issuer=/C=US/O=Apple Inc./OU=Apple Worldwide Developer Relations/CN=Apple Worldwide Developer Relations Certification Authority
    -----BEGIN CERTIFICATE-----
    ... snip ...
    -----END CERTIFICATE-----
    Bag Attributes
        friendlyName: User Name
        localKeyID: ... snip ...
    Key Attributes: <No Attributes>
    Enter PEM pass phrase:
    Verifying - Enter PEM pass phrase:
    -----BEGIN ENCRYPTED PRIVATE KEY-----
    ... snip ...
    -----END ENCRYPTED PRIVATE KEY-----
    Bag Attributes
        friendlyName: User Name
        localKeyID: ... snip ...
    Key Attributes: <No Attributes>
    Enter PEM pass phrase:
    Verifying - Enter PEM pass phrase:
    -----BEGIN ENCRYPTED PRIVATE KEY-----
    ... snip ...
    -----END ENCRYPTED PRIVATE KEY-----
    

    您可以在此处看到 PKCS12 文件包含 2 个证书和 2 个私钥(实际上是同一密钥的 2 个副本),每个用于不同的 App ID。列出的第一个是预期的 App ID,而第二个是我们使用的不同应用程序。

    这个文件被读入KeyStore,随后被传递给SSLSocket以连接到Apple。这样做如下:

        String password = "my_password";
        KeyStore.ProtectionParameter pwParam = new KeyStore.PasswordProtection(password.toCharArray());
        KeyStore keystore = KeyStore.getInstance("PKCS12");
        System.out.println("keystore classname: " + keystore.getClass().getName());
        FileInputStream fileStream = new FileInputStream("certificate_file.p12");
        keystore.load(fileStream, password.toCharArray());
        for (Enumeration<String> e = keystore.aliases(); e.hasMoreElements(); ) {
                String alias = e.nextElement();
                System.out.println("*** entry name: " + alias);
                KeyStore.Entry entry = keystore.getEntry(alias, pwParam);
                System.out.println("entry as string: " + entry.toString());
                for (Certificate cert: keystore.getCertificateChain(alias)) {
                        System.out.println("*** cert: " + cert);
                }
        }
    

    在 Java 6 下,运行上述代码会得到以下结果:

    keystore classname: java.security.KeyStore
    *** entry name: User Name
    entry as string: Private key entry and certificate chain with 1 elements:
    [
    [
      Version: V3
      Subject: C=US, OU=PRXXXXXXXX, CN=Apple Development IOS Push Services: app.id.1, UID=app.id.1
    
    ....
    

    在 Java 7 或 8 下,我们得到:

    keystore classname: java.security.KeyStore
    *** entry name: User Name
    entry as string: Private key entry and certificate chain with 1 elements:
    [
    [
      Version: V3
      Subject: C=US, OU=PRXXXXXXXX, CN=Apple Development IOS Push Services: app.id.2, UID=app.id.2
    

    因此,由于两个证书引用相同的私钥,一个会覆盖另一个,因此KeyStore 仅包含两个证书之一。在 Java 6 下,保留第一个证书,而 Java 7 和 8 保留第二个证书。因此,当与 Apple 建立连接时,它会发送错误的证书,并且发送的任何推送都被视为无效,因为正在发送的推送令牌的 App ID 与用于连接的证书的 App ID 不匹配。

    要解决此问题,应仅使用预期的 App ID 生成 PKCS12 文件。这可确保读取正确的证书并随后用于连接到 Apple。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-03
      • 1970-01-01
      • 2013-07-07
      相关资源
      最近更新 更多