我在 Android 上使用 HttpClient 连接到https://someUrl.com/somePath。问题是该站点的证书适用于 *.someUrl.com,而不是 someUrl.com,所以我得到了 SSLException。是的,网站方面很蹩脚,但除非我能修复它,否则我会被卡住。有没有办法让 HttpClient 放松并接受证书?
问问题
26592 次
4 回答
33
这是我的(编辑)解决方案:
class MyVerifier extends AbstractVerifier {
private final X509HostnameVerifier delegate;
public MyVerifier(final X509HostnameVerifier delegate) {
this.delegate = delegate;
}
@Override
public void verify(String host, String[] cns, String[] subjectAlts)
throws SSLException {
boolean ok = false;
try {
delegate.verify(host, cns, subjectAlts);
} catch (SSLException e) {
for (String cn : cns) {
if (cn.startsWith("*.")) {
try {
delegate.verify(host, new String[] {
cn.substring(2) }, subjectAlts);
ok = true;
} catch (Exception e1) { }
}
}
if(!ok) throw e;
}
}
}
public DefaultHttpClient getTolerantClient() {
DefaultHttpClient client = new DefaultHttpClient();
SSLSocketFactory sslSocketFactory = (SSLSocketFactory) client
.getConnectionManager().getSchemeRegistry().getScheme("https")
.getSocketFactory();
final X509HostnameVerifier delegate = sslSocketFactory.getHostnameVerifier();
if(!(delegate instanceof MyVerifier)) {
sslSocketFactory.setHostnameVerifier(new MyVerifier(delegate));
}
return client;
}
它的优点是除非存在通配符域,否则不会更改默认行为,在这种情况下,它会重新验证,就好像 2 部分域(例如,someUrl.com)是证书的一部分,否则会重新抛出原始异常。这意味着真正无效的证书仍然会失败。
于 2010-06-28T23:55:23.363 回答
3
Android 上的 BouncyCastle 太旧,无法识别通配符证书。
您可以编写自己的 X509TrustManager 来检查通配符。
或者,如果您可以接受风险,则可以完全禁用证书检查。看到这个问题,
于 2010-06-28T21:34:37.583 回答
1
如果它想要*.someUrl.com
,那么看起来你可以给它www.someUrl.com/somePath
而不是someUrl.com/somePath
.
于 2010-06-28T19:59:17.633 回答
1
如果您使用 WebView 只需调用
webview.clearSslPreferences();
忽略 SSL 错误
于 2011-10-07T15:17:09.343 回答