SSLSocket via another SSLSocket
我正在尝试在Android应用程序中创建另一个之上。下部连接是与安全 Web 代理(基于 SSL 的 HTTP 代理)的 SSL 安全连接,上部连接用于 HTTP over SSL (HTTPS)。SSLSocket
SSLSocket
为此,我正在使用SSSOCKetFactory的函数,该函数允许传递一个现有的Socket来运行SSL连接,如下所示:createSocket()
private Socket doSSLHandshake(Socket socket, String host, int port) throws IOException {
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager(){
public X509Certificate[] getAcceptedIssuers(){ return null; }
public void checkClientTrusted(X509Certificate[] certs, String authType) {}
public void checkServerTrusted(X509Certificate[] certs, String authType) {}
}
};
try {
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new SecureRandom());
SSLSocket sslSocket = (SSLSocket) sslContext.getSocketFactory().createSocket(socket, host, port, true);
sslSocket.setEnabledProtocols(sslSocket.getSupportedProtocols());
sslSocket.setEnableSessionCreation(true);
sslSocket.startHandshake();
return sslSocket;
} catch (KeyManagementException | NoSuchAlgorithmException e) {
throw new IOException("Could not do handshake: " + e);
}
}
当底层套接字是普通的 tcp 套接字时,此代码工作正常,但是当我使用之前使用上述代码创建的 SSLSocket 作为基础套接字时,握手失败,出现以下异常:
javax.net.ssl.SSLHandshakeException: Handshake failed
at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:429)
at com.myapp.MyThreadClass.doSSLHandshake(MyThreadClass.java:148)
at com.myapp.MyThreadClass.run(MyThreadClass.java:254)
Caused by: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x7374d56e80: Failure in SSL library, usually a protocol error
error:100000e3:SSL routines:OPENSSL_internal:UNKNOWN_ALERT_TYPE (external/boringssl/src/ssl/s3_pkt.c:618 0x738418ce7e:0x00000000)
at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:357)
... 2 more
我正在Android 7.1.1上进行测试。该应用面向 SDK 级别 23。
- 我做错了什么?
- 如何进一步调试问题?
- 有没有人有一个SSLSocket在最近的Android版本上超越另一个SSLSocket的工作示例?
任何帮助都非常感谢!
更新:完全相同的代码适用于Mac上的JRE 1.8,但不适用于Android。
更新 2:从概念上讲,这些是连接所经历的步骤:
- 从 Android 应用中,连接到安全代理服务器(套接字)
- 与代理服务器进行 SSL/TLS 握手(SSLSocket over Socket)
- 通过 SSLSocket,将 CONNECT 消息发送到代理服务器
- 代理连接到目标 (https) 服务器,从现在开始仅复制字节
- 与目标 (https) 服务器执行 SSL/TLS 握手(SSLSocket over SSLSocket over Socket)
- 将 GET 消息发送到目标服务器并读取响应
问题出现在步骤 5 中,当在经过 SSLSocket(通过套接字)的 SSLSocket 上进行握手时。
更新3:我现在打开了一个GitHub存储库,其中包含一个示例项目和tcpdumps:https://github.com/FD-/SSLviaSSL
注意:我发现并阅读了一个标题非常相似的问题,但不幸的是,它不包含太多有用的帮助。