javax.net.ssl.SSLHandshakeException:收到致命警报:handshake_failure错误APN

问题描述:

我试图使用Java的PNS推送通知发送到iPhone,但我收到以下错误......javax.net.ssl.SSLHandshakeException:收到致命警报:handshake_failure错误APN

javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure 

这是我的代码...

String token="95076d2846e8979b46efd1884206a590d99d0f3f6139d947635ac4186cdc5942"; 

String host = "gateway.sandbox.push.apple.com"; 
int port = 2195; 
String payload = "{\"aps\":{\"alert\":\"Message from Java o_O\"}}"; 

NotificationTest.verifyKeystore("res/myFile.p12", "password", false); 
KeyStore keyStore = KeyStore.getInstance("PKCS12"); 
keyStore.load(getClass().getResourceAsStream("res/myFile.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(); 

System.out.println("Message sent .... "); 

对于NotificationTest.verifyKeystore我得到这个有效的是FileKeystore

我不理解为什么我得到这个错误。

这是我的错误日志...

** CertificateRequest 
Cert Types: RSA, DSS, ECDSA 
Cert Authorities: 
<empty> 
[read] MD5 and SHA1 hashes: len = 10 
0000: 0D 00 00 06 03 01 02 40 00 00 [email protected] 
** ServerHelloDone 
[read] MD5 and SHA1 hashes: len = 4 
0000: 0E 00 00 00 .... 
** Certificate chain 
** 
** ClientKeyExchange, RSA PreMasterSecret, TLSv1 
[write] MD5 and SHA1 hashes: len = 269 
... 
main, READ: TLSv1 Alert, length = 2 
main, RECV TLSv1 ALERT: fatal, handshake_failure 
main, called closeSocket() 
main, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure 

我不理解为什么当局证书是空的?

+0

正如[本答案](http://*.com/a/11050271/372643)中所述,请不要启用所有*支持*密码套件。其中一些由默认情况下未启用支持,因为它们不安全。 – Bruno

发送推送通知到iPhone/iPad我已经使用JavaPNS

这是非常容易使用,它为我工作。

我们只需关注This即可使用它。

我建议您使用keytool -list将客户机上的密钥库与服务器已知的密钥库进行比较。您收到的握手错误是因为服务器已经完成了问候,并期待客户端证书的回复。你没有发送一个。要解决这个问题,应该将PKCS12证书转换为PEM格式(使用openssl是一种方式),然后使用keytool导入到密钥库中。

我怀疑,如果你通过将密钥库导入客户端证书来解决这个问题,那么你将会遇到第二个错误。第二个错误是关于空的CA证书 - 可能是因为您的密钥库中没有服务器已知的CA证书。导入您的CA并重试。

+0

谢谢snow6oy的回复。我会试试看。 – Deepu

看起来您需要安装“Java加密扩展(JCE)无限强度管辖权策略文件”。这解决了我的问题。