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

Posted

技术标签:

【中文标题】获取 javax.net.ssl.SSLHandshakeException:收到致命警报:handshake_failure 错误【英文标题】:Getting javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure Error 【发布时间】:2012-06-18 07:30:18 【问题描述】:

我正在尝试使用 Java-pns 向 iPhone 发送推送通知,但出现以下错误 - javax.net.ssl.SSLHandshakeException:收到致命警报: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 我知道这个有效的是文件和密钥库。

我不明白为什么会出现此错误。

有人可以帮帮我吗?

提前致谢...

在我的日志中我看到了

** 证书请求

证书类型:RSA、DSS、ECDSA

证书颁发机构:

[读取] MD5 和 SHA1 哈希:len = 10

0000: 0D 00 00 06 03 01 02 40 00 00 .......@..

** 服务器HelloDone

[读取] MD5 和 SHA1 哈希:len = 4

0000: 0E 00 00 00 ....

** 证书链

**

** ClientKeyExchange、RSA PreMasterSecret、TLSv1

[写入] MD5 和 SHA1 哈希:len = 269

.

.

.

.

.

主,阅读:TLSv1 警报,长度 = 2

main,RECV TLSv1 ALERT:致命,handshake_failure

main,调用closeSocket()

main,处理异常:javax.net.ssl.SSLHandshakeException:收到致命警报: 握手失败

我不明白为什么 Cert Authorities: 为空?

【问题讨论】:

你能发布完整的堆栈跟踪吗? 【参考方案1】:

如果没有看到堆栈跟踪以及使用-Djavax.net.debug=ssl,handshake. 运行客户端或服务器时可能产生的输出,就无法回答但是:

String[] cipherSuites = sslSocket.getSupportedCipherSuites(); sslSocket.setEnabledCipherSuites(cipherSuites);

不要那样做。它根本不安全,它只是隐藏了真正的问题,这几乎总是一个证书信任链问题:要么客户端不信任服务器的证书,反之亦然。

【讨论】:

感谢 EJP 的回复。我正在使用 cipherSuites = sslSocket.get... 请建议我改用什么。 @DeepakPawar,通常情况下,使用默认密码套件就可以了。不要设置任何东西。另外,您不需要显式调用startHandshake,它会在您开始从输出流中读取时完成。 谢谢布鲁诺,我会试试的

以上是关于获取 javax.net.ssl.SSLHandshakeException:收到致命警报:handshake_failure 错误的主要内容,如果未能解决你的问题,请参考以下文章

js如何获取某一个元素,如果获取不到就继续获取,直到获取到后停止获取?

iOS ---------- 获取设备的各种信息

java反射获取属性值

Shell 获取路径

iOS 获取文件大小

根据日期字符串获取星期几,日期获取星期,时间获取星期,js获取星期