java - 通过 Java 与 Apple 推送通知服务器进行 SSL 握手

标签 java ssl apple-push-notifications

您好,我正在尝试使用 Java 向我的设备发送推送消息。但我在建立 ssl 连接时已经遇到问题了。 这是到目前为止的代码:

        KeyStore keyStore = KeyStore.getInstance("PKCS12");

        InputStream key = getClass().getResourceAsStream("apns-dev-key.p12");
        char[] c = key.toString().toCharArray();

        keyStore.load(getClass().getResourceAsStream("apns-dev-cert.p12"), c);
        KeyManagerFactory keyMgrFactory = KeyManagerFactory.getInstance("SunX509");
        keyMgrFactory.init(keyStore, c);

        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(keyMgrFactory.getKeyManagers(), null, null);
        SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

        SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket(host, port);
        String[] cipherSuites = sslSocket.getSupportedCipherSuites();
        sslSocket.setEnabledCipherSuites(cipherSuites);
        sslSocket.startHandshake();

我收到的错误是:

java.io.IOException: failed to decrypt safe contents entry: javax.crypto.BadPaddingException: Given final block not properly padded

我猜 apns-dev-key.p12 文件有问题。有什么提示吗?

以上代码取自:http://undermypalapa.wordpress.com/2009/08/23/apple-push-notification-service-java/

最佳答案

这是我的工作示例:

private String token = "<token>";
private String host = "gateway.sandbox.push.apple.com";
private int port = 2195;

private String payload = "{\"aps\":{\"alert\":\"Message from Java o_O\"}}";

public APNSender() {
    try {
        KeyStore keyStore = KeyStore.getInstance("PKCS12");

        keyStore.load(getClass().getResourceAsStream("cert.p12"), "<password>".toCharArray());
        KeyManagerFactory keyMgrFactory = KeyManagerFactory.getInstance("SunX509");
        keyMgrFactory.init(keyStore, "<password>".toCharArray());

        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(keyMgrFactory.getKeyManagers(), null, null);
        SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

        SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket(host, port);
        String[] cipherSuites = sslSocket.getSupportedCipherSuites();
        sslSocket.setEnabledCipherSuites(cipherSuites);
        sslSocket.startHandshake();

        char[] t = token.toCharArray();
        byte[] b = Hex.decodeHex(t);

        OutputStream outputstream = sslSocket.getOutputStream();

        outputstream.write(0);
        outputstream.write(0);
        outputstream.write(32);
        outputstream.write(b);
        outputstream.write(0);
        outputstream.write(payload.length());
        outputstream.write(payload.getBytes());

        outputstream.flush();
        outputstream.close();

    } catch (Exception exception) {
        exception.printStackTrace();
    }
}

我仍然好奇的是如何接收错误代码。我尝试过

InputStream in = sslSocket.getInputStream(); 
[...]   

但没有成功。

Apple docs说没有发生错误时没有发送应答,但另一方面,他们列出了“未遇到错误”的状态代码。

关于java - 通过 Java 与 Apple 推送通知服务器进行 SSL 握手,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9410249/

相关文章:

ios - iOS 推送通知和远程通知之间的区别?

java - 过期 session 出现 NullPointerException

java - 为什么老年代对象会被小 GC 清除

ssl - force_ssl 甚至落后于 nginx 并生成 https url

php - 如何修复 https 错误

ios - 为什么deviceToken是以NSData类型传递的,在application :didRegisterForRemoteNotificationsWithDeviceToken?

java - 将 JPanels 置于角落?

java - 无法调用 rest cxf 服务

ssl - keytool 找不到别名

actionscript-3 - 从 AIR 桌面客户端发送推送通知,无需中间件(例如 PHP)