2012-02-23 38 views
2

您好,我正嘗試使用Java向我的設備發送推送消息。但是我在建立ssl連接時已經遇到了問題。 這是迄今爲止代碼:通過Java與Apple推送通知服務器進行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-ke​​y.p12文件。任何提示?

上面的代碼摘自:http://undermypalapa.wordpress.com/2009/08/23/apple-push-notification-service-java/

+1

好吧,我現在正在工作。問題是我試圖使用apns-dev-key.p12。但我所需要做的就是使用推送證書(包含證書和密鑰的p12文件)並使用我在導出證書時創建的密碼。 – Pathos 2012-02-23 10:38:02

回答

3

這裏我的工作例如:

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表示在沒有錯誤發生時沒有應答發送,但是另一方面他們列出了「沒有遇到錯誤」的狀態碼。

+0

請勿啓用所有受支持的密碼套件。其中一些由於充分的原因而被默認禁用。 – Bruno 2012-05-02 19:21:26

+0

這可以用pem做嗎? – 2015-06-24 14:02:57

0

你可能想看看http://code.google.com/p/javapns/。如果您真的需要重新發明輪子,而不是直接使用JavaPNS而不是爲此編寫自己的代碼,那麼至少JavaPNS的文檔應該可以幫助您理解您需要知道的關鍵原則。