2010-06-28 101 views

回答

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)是证书的一部分,否则重新生成原始异常。这意味着真正无效的证书仍然会失败。

+0

我试过使用上面的方法,但有时会出现堆栈溢出异常 - verify()方法从不停止递归。在几十万次安装中,它每周发生约80次。你有没有看到这个问题? – user291701 2010-10-28 15:32:08

+0

@ user291701我编辑了代码以尝试解决您的问题。我猜想问题是你最终再次在同一个工厂设置验证程序,所以它最终会以某种方式委托给自己......如果找到更好的方法,请随时编辑我的答案。 – noah 2010-11-02 13:41:52

+0

在任何情况下,我面临'服务器无法为请求提供服务,因为媒体类型不受支持''错误。没有得到任何关于这个原因的线索。 – 2016-04-05 13:07:11

1

如果它想要*.someUrl.com,那么看起来你可以给它www.someUrl.com/somePath而不是someUrl.com/somePath

+1

都能跟得上。 www.someUrl.com重定向到someUrl.com – noah 2010-06-28 20:06:18

+0

那么我认为那没用。你真的需要https吗?我会这样猜测,但那会让生活变得更容易。 – 2010-06-28 20:16:26

+0

当网站不做重定向时,这是一个很好的临时解决方案! – 2012-04-17 13:12:32

3

Android上的BouncyCastle太旧,无法识别通配符证书。

您可以编写自己的X509TrustManager来检查通配符。

或者您可以完全禁用证书检查,如果您可以接受风险。看到这个问题,

Self-signed SSL acceptance on Android

+0

其实ZZ,如果OP是正确的关于网站的名称和证书的结构,那么错误信息是正确的:**。someUrl.com *应该匹配www.someUrl.com和anything.someUrl。 com,但*不* someUrl.com或this.that.someUrl.com。 – 2010-06-29 00:00:05

1

,如果你使用的WebView只需调用

webview.clearSslPreferences(); 

忽略SSL错误

相关问题