gpt4 book ai didi

android - Android 的 SSL 问题

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:00:45 26 4
gpt4 key购买 nike

我的 Android 设备上有一个非常具体的 SSL 问题。如果我尝试通过代码访问特定网站,我会收到以下错误:

SSL handshake failure: Failure in SSL library, usually a protocol error
error:140773F2:SSL routines:SSL23_GET_SERVER_HELLO: sslv3 alert unexpected message (external/openssl/ssl/s23_cInt.c:500 0xaf076228:0x00000000)

无论构建如何,我都会得到这个...我已经在 API 级别 1.5、1.6、2.2 和 4.0 上尝试过,每次都得到相同的结果。

经过一些故障排除后,我尝试通过浏览器访问该网站,但出现以下错误:

Data connectivity problem
A secure connection could not be established.

事情是这样的……该网站在 Windows 浏览器上打开得很好(在 Firefox、IE 和 Chrome 上测试过)。它也可以在使用与 Android 相同的 webkit 的 iOS 设备上正常打开,这很奇怪。该网站在 Opera Mini 浏览器上也能正常运行。

Here's the website.

我已经尝试通过将客户端证书添加到 keystore 并忽略无效的客户端证书来尝试解决方法,但没有结果。但是,证书本身似乎不是问题。

我陷入了僵局。任何人都可以提供任何关于如何让它工作的指导吗?

最佳答案

我找到了解决方案(感谢 Nikolay 为我指明了正确的方向)。

问题有两个方面...第一,它返回了 Android 不喜欢的站点证书,第二,它只启用了 SSLv3(而不是 TLS)。

这是我的解决方案。首先,我必须创建一个自定义套接字工厂类:

public class MySSLSocketFactory extends SSLSocketFactory {
SSLContext sslContext = SSLContext.getInstance("SSLv3");

public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
super(truststore);

TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};

sslContext.init(null, new TrustManager[] { tm }, null);
}

@Override
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
SSLSocket S = (SSLSocket) sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
S.setEnabledProtocols(new String[] {"SSLv3"});
return S;
}

@Override
public Socket createSocket() throws IOException {
SSLSocket S = (SSLSocket) sslContext.getSocketFactory().createSocket();
S.setEnabledProtocols(new String[] {"SSLv3"});
return S;
}

其次,我在代码中定义了这个自定义 HttpClient:

public HttpClient getNewHttpClient() {
try {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);

MySSLSocketFactory sf = new MySSLSocketFactory(trustStore);
sf.setHostnameVerifier(MySSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);

SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
registry.register(new Scheme("https", sf, 443));

ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);

return new DefaultHttpClient(ccm, params);
} catch (Exception e) {
return new DefaultHttpClient();
}
}

第三,我调用了自定义的HttpClient并解析了结果:

public String test(String URIString) {
HttpClient httpClient = getNewHttpClient();
String result = "";
URI uri;
try {
uri = new URI(URIString);
} catch (URISyntaxException e1) {
return "ERROR";
}
HttpHost host = new HttpHost(uri.getHost(), 443, uri.getScheme());
HttpPost httppost = new HttpPost(uri.getPath());
try {
HttpResponse response = httpClient.execute(host, httppost);
BufferedReader reader = new BufferedReader(
new InputStreamReader(
response.getEntity().getContent()
)
);
String line = null;
while ((line = reader.readLine()) != null){
result += line + "\n";
}

return result;
} catch (ClientProtocolException e) {
return "ERROR";
} catch (IOException e) {
return "ERROR";
}
}

关于android - Android 的 SSL 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11141086/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com