java 无法使用 Javapns/Javaapns SSL 握手失败发送推送通知

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12585858/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 09:26:57  来源:igfitidea点击:

Cannot send push notifications using Javapns/Javaapns SSL handshake failure

javassl-certificateapple-push-notifications

提问by user1192724

I have an issue with push notifications. I have a p.12 certificate that was created by a team member and I have the device token for the device to be pushed to. I am using the javapns library to do the push (also tried the javaapns lib with same results) but I keep getting this error:

我有推送通知问题。我有一个由团队成员创建的 p.12 证书,并且我有要推送到的设备的设备令牌。我正在使用 javapns 库进行推送(也尝试了 javaapns 库,结果相同)但我不断收到此错误:

javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1720)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:954)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1138)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:632)
at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:59)
at java.io.OutputStream.write(OutputStream.java:58)
at javapns.notification.PushNotificationManager.sendNotification(PushNotificationManager.java:402)
at javapns.notification.PushNotificationManager.sendNotification(PushNotificationManager.java:350)
at javapns.notification.PushNotificationManager.sendNotification(PushNotificationManager.java:320)
at javapns.Push.sendPayload(Push.java:177)
at javapns.Push.combined(Push.java:100)
at PushTest.push(PushTest.java:43)
at PushTest.main(PushTest.java:25)

and this is the code I am using to test

这是我用来测试的代码

try {
    List<PushedNotification> n = Push.combined(text, 20, null, file, "********", false, token);

    for (PushedNotification notification : n) {
        if (notification.isSuccessful())  
            System.out.println("Push notification sent successfully to: " + notification.getDevice().getToken());
        else {
            String invalidToken = notification.getDevice().getToken();

            Exception theProblem = notification.getException();
            theProblem.printStackTrace();

            ResponsePacket theErrorResponse = notification.getResponse();
            if (theErrorResponse != null)
                System.out.println(theErrorResponse.getMessage());
        }
    }
}
catch (CommunicationException e)  {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
catch (KeystoreException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

I read and tried the suggestions from several of the other posts including importing the certificate into cacerts keystore but the import fails as well. I am developing using eclipse on a windows machine.

我阅读并尝试了其他几篇文章中的建议,包括将证书导入 cacerts 密钥库,但导入也失败了。我正在 Windows 机器上使用 eclipse 进行开发。

Anyone familiar with this issue? I am new to using ssl so perhaps I'm doing something wrong or is it that I cannot use a certificate generated on another machine?

有人熟悉这个问题吗?我是使用 ssl 的新手,所以也许我做错了什么,或者我不能使用在另一台机器上生成的证书?

回答by Sunny

I am a new iOS developer and I had the same issue before.

我是一名新的 iOS 开发人员,之前也遇到过同样的问题。

I finally found that the problem was due to the p12 certificate. We should not use the private key p12 file, instead we should generate a p12 from your private key and the cert download from Apple.

我终于发现问题是由于p12 certificate. 我们不应该使用私钥 p12 文件,而是应该从您的私钥和从 Apple 下载的证书生成 p12。

Please execute the following OpenSSL command to get the correct p12 file:

请执行以下 OpenSSL 命令以获取正确的 p12 文件:

developer_identity.cer <= download from Apple
mykey.p12 <= Your private key

openssl x509 -in developer_identity.cer -inform DER -out developer_identity.pem -outform PEM
openssl pkcs12 -nocerts -in mykey.p12 -out mykey.pem
openssl pkcs12 -export -inkey mykey.pem -in developer_identity.pem -out iphone_dev.p12

After that, you should use iphone_dev.p12to communicate with apple server.

之后,您应该使用iphone_dev.p12与苹果服务器进行通信。

回答by Delorean

Sunny's answeris a great one, but unfortunately it didn't work for me.

Sunny 的回答很好,但不幸的是它对我不起作用。

I got it working by exporting the certificate/private key pair from the keychain. The trick is that the selection sequence matters! The certificate has to be selected first, followed by the private key.

我通过从钥匙串导出证书/私钥对来让它工作。诀窍是选择顺序很重要!必须首先选择证书,然后是私钥。

Here is how it works:

下面是它的工作原理:

  1. Import the certificate downloaded from Apple into the keychains
  2. Expand so that the private key is visible
  3. Select the certificate followed by the private key
  4. Right click and choose [Export 2 items...]
  1. 将苹果下载的证书导入钥匙串
  2. 展开以便私钥可见
  3. 选择证书后跟私钥
  4. 右键单击并选择 [导出 2 个项目...]