使用 HTTPS 协议的 android 连接中的 Socket.io 客户端失败?
Posted
技术标签:
【中文标题】使用 HTTPS 协议的 android 连接中的 Socket.io 客户端失败?【英文标题】:Socket.io client in android connection with HTTPS protocol failed? 【发布时间】:2016-10-16 01:18:41 【问题描述】:服务器上的io和android上的客户端。
只要我启用 HTTP(S) SSL,它就会在 android 上导致连接错误(但是如果禁用它可以正常工作)
我尝试在 Android 上实现 HTTPS 连接,参考 Github 上的示例如下:
opts = new IO.Options();
opts.sslContext = mySSLContext;
opts.hostnameVerifier = myHostnameVerifier;
socket = IO.socket("https://mychat.url", opts);
还有这个
SSLContext mySSLContext = SSLContext.getInstance("TLS");
mySSLContext.init(null, null, null);
还有这个
myHostnameVerifier = new HostnameVerifier()
@Override
public boolean verify(String hostname, SSLSession session)
return true;
);
在套接字传输过程中仍然收到错误消息
io.socket.engineio.client.EngineIOException: xhr poll error
javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
使用 HTTPS 协议实现 socket io 连接需要什么?
【问题讨论】:
我不确定,但可能是信任管理器问题,请查看developer.android.com/training/articles/security-ssl.html @Apurva 谢谢你,我自己解决了。是的,这是 trustManager 问题。 【参考方案1】:感谢@Apurva,我自己解决了。
似乎需要 TrustManager 来初始化 sslContext
所以我加了
mySSLContext.init(null, trustAllCerts, null);
带参数trustAllCerts参考
private final TrustManager[] trustAllCerts= new TrustManager[] new X509TrustManager()
public java.security.cert.X509Certificate[] getAcceptedIssuers()
return new java.security.cert.X509Certificate[] ;
public void checkClientTrusted(X509Certificate[] chain,
String authType) throws CertificateException
public void checkServerTrusted(X509Certificate[] chain,
String authType) throws CertificateException
;
终于成功连接到聊天服务器了。
【讨论】:
绝对不可思议!【参考方案2】:感谢@Dayo Chou,我通过 https 获得了 socket.io 连接。我正在阅读https://github.com/socketio/socket.io-client-java,但它并没有告诉你你需要的一切。这篇文章仍然缺少这些内容,所以我决定将我的代码发布给任何可能觉得它有用的人。更改 ADDRESS 和 PORT 以满足您的需求。
HostnameVerifier myHostnameVerifier = new HostnameVerifier()
@Override
public boolean verify(String hostname, SSLSession session)
return true;
;
TrustManager[] trustAllCerts= new TrustManager[] new X509TrustManager()
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException
public X509Certificate[] getAcceptedIssuers()
return new X509Certificate[0];
;
SSLContext mySSLContext = null;
try
mySSLContext = SSLContext.getInstance("TLS");
try
mySSLContext.init(null, trustAllCerts, null);
catch (KeyManagementException e)
e.printStackTrace();
catch (NoSuchAlgorithmException e)
e.printStackTrace();
OkHttpClient okHttpClient = new OkHttpClient.Builder().hostnameVerifier(myHostnameVerifier).sslSocketFactory(mySSLContext.getSocketFactory()).build();
// default settings for all sockets
IO.setDefaultOkHttpWebSocketFactory(okHttpClient);
IO.setDefaultOkHttpCallFactory(okHttpClient);
// set as an option
IO.Options opts = new IO.Options();
opts.callFactory = okHttpClient;
opts.webSocketFactory = okHttpClient;
socket = IO.socket("https://" + ADDRESS + ":PORT", opts);
socket.connect();
【讨论】:
我尝试了您的解决方案,但唉!连接似乎卡在“正在连接”上。我从来没有收到来自服务器的Socket.EVENT_CONNECT
,只有Socket.EVENT_CONNECTING
...
在 Android API 中运行时对我不起作用
@Hayuki 尝试添加这一行:opts.transports = new String[] WebSocket.NAME ;【参考方案3】:
Kotlin 版本:
val myHostnameVerifier = HostnameVerifier _, _ ->
return@HostnameVerifier true
val trustAllCerts = arrayOf<TrustManager>(object : X509TrustManager
override fun checkClientTrusted(chain: Array<X509Certificate>, authType: String)
override fun checkServerTrusted(chain: Array<X509Certificate>, authType: String)
override fun getAcceptedIssuers(): Array<X509Certificate>
return arrayOf()
)
val sslContext = SSLContext.getInstance("TLS")
sslContext.init(null, trustAllCerts, null)
val okHttpClient = OkHttpClient.Builder()
.hostnameVerifier(myHostnameVerifier)
.sslSocketFactory(sslContext.socketFactory, trustAllCerts[0] as X509TrustManager)
.build()
val options = IO.Options()
options.transports = arrayOf(Polling.NAME)
options.callFactory = okHttpClient
options.webSocketFactory = okHttpClient
val socket = IO.socket("https://...", options)
socket.connect()
【讨论】:
以上是关于使用 HTTPS 协议的 android 连接中的 Socket.io 客户端失败?的主要内容,如果未能解决你的问题,请参考以下文章
android黑科技系列——Wireshark和Fiddler分析Android中的TLS协议包数据(附带案例样本)
Wireshark和Fiddler分析Android中的TLS协议包数据(附带案例样本)
Android实战之旅 006Android中的HTTP通信