我正在尝试在支持通过 SSL 进行安全传输的应用程序中实现 WebSocket 客户端。该应用程序已经通过实现自定义 key 和信任管理器支持基于 HTTP 的标准 SSL 连接(这些自定义实现已到位以在需要时提示用户输入证书)。
我无法安全连接到我们的远程 WebSocket 端点。故障发生在握手期间。我尝试了两种不同的 WebSocket API 实现(Tyrus 和 Jetty),但都以同样的方式失败,这当然让我想到了我们的 SSL 实现。
正如我所提到的,失败发生在握手期间。似乎连接无法确定存在由服务器返回的受支持机构签署的客户端证书。我很难弄清楚是不是我没有正确地向 WebSocket API 提供客户端证书,或者我们的自定义 key /信任管理器是否正在被使用。
这是 SSL 调试日志的转储:
*** CertificateRequest
Cert Types: RSA, DSS
Cert Authorities:
(list of about 15 cert authorities supported by the server)
*** ServerHelloDone
Warning: no suitable certificate found - continuing without client authentication
*** CertificateChain
<empty>
***
我在我们的 TrustManager 实现中设置了断点,以确定它们是否曾经被调用,但似乎此时它们没有被调用。
几天来我一直在尝试调试它,但我已经没有什么可以尝试的了。
如有任何建议,我们将不胜感激!
这是 Jetty 代码的片段:
SSLContext context = SSLContext.getInstance("TLS");
// getKeyManagers / getTrustManagers retrieves an
// array containing the custom key and trust manager
// instances:
KeyManager[] km = getKeyManagers();
TrustManager[] tm = getTrustManagers();
context.init(km, tm, null);
SslContextFactory contextFactory = new SslContextFactory();
contextFactory.setContext(context);
WebSocketClient client = new WebSocketClient(contextFactory);
SimpleEchoClient echoClient = new SimpleEchoClient();
try {
client.start();
ClientUpgradeRequest request = new ClientUpgradeRequest();
Future<Session> connection = client.connect(echoClient, uri, request);
Session session = connection.get();
// if everything works, do stuff here
session.close();
client.destroy();
} catch (Exception e) {
LOG.error(e);
}
最佳答案
您可以尝试使用 rejectUnAuthorized:false 以便您的浏览器无法授权的证书将跳过授权。
var ws = new WebSocket('wss://localhost:xxxx', {
protocolVersion: 8,
origin: 'https://localhost:xxxx',
rejectUnauthorized: false
});
关于Java8 安全 WebSocket 握手问题(Tyrus 和 Jetty),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44785125/