Android HttpClient - 证书中的主机名与 不匹配!= <*.example.com>;

发布于 2024-09-07 13:07:40 字数 245 浏览 7 评论 0 原文

我在 Android 上使用 HttpClient 连接到 https://someUrl.com/somePath。问题是该网站的证书适用于 *.someUrl.com,而不是 someUrl.com,因此我收到 SSLException。是的,该网站的部分很蹩脚,但除非我能修复它,否则我就陷入困境。有没有办法让 HttpClient 放松并接受证书?

I'm using HttpClient on Android to connect to https://someUrl.com/somePath. The problem is that the site's certificate is for *.someUrl.com, not someUrl.com, so I get an SSLException. Lame on the part of the site, yes, but unless I can get it fixed, I'm stuck. Is there a way I can get HttpClient to relax and accept the certificate?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

韵柒 2024-09-14 13:07:40

这是我的(编辑过的)解决方案:

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;
}

它的优点是不更改默认行为,除非存在通配符域,在这种情况下,它会重新验证,就好像两部分域(例如,someUrl.com)是证书的一部分一样,否则将重新抛出原始异常。这意味着真正无效的证书仍然会失败。

This is my (edited) solution:

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;
}

It has the advantage of not changing the default behavior unless there is a wildcard domain, and in that case it revalidates as though the 2 part domain (e.g., someUrl.com) were part of the certificate, otherwise the original exception is rethrown. That means truly invalid certs will still fail.

牵你的手,一向走下去 2024-09-14 13:07:40

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

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

或者,如果您可以接受风险,则可以完全禁用证书检查。请参阅此问题,

Android 上的自签名 SSL 接受

The BouncyCastle on Android is too old and it doesn't recognize wildcard certificate.

You can write your own X509TrustManager to check for wildcard.

or you can disable certificate check altogether if you can accept the risk. See this question,

Self-signed SSL acceptance on Android

感受沵的脚步 2024-09-14 13:07:40

如果它想要 *.someUrl.com,那么您似乎可以直接给它 www.someUrl.com/somePath 而不是 someUrl.com/somePath< /代码>。

If it wants *.someUrl.com, then it seems like you could just give it www.someUrl.com/somePath instead of someUrl.com/somePath.

滴情不沾 2024-09-14 13:07:40

如果您使用 WebView 只需调用

webview.clearSslPreferences();

忽略 SSL 错误

if you use a WebView just call

webview.clearSslPreferences();

to ignore SSL errors

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文