接受自签名SSL证书 - >在哪里设置默认的TrustManager [英] accept self-signed SSL Certificates-> where to set default TrustManager

查看:325
本文介绍了接受自签名SSL证书 - >在哪里设置默认的TrustManager的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,我不得不承认,我知道接受所有证书可被视为没有安全保障。我们有真正的Certs,但仅限于我们的实时系统。我们的测试系统上的证书是自签名的。因此,只要我们开发,我们就必须使用测试服务器,这会迫使我禁用证书。

First I had to admit that I know that accepting all certs can be considered as having no security. We have "real" Certs but only on our live systems. The certs on our test systems are self-signed. So as long we're developing, we have to use test-servers, which forces me to kind of disable certificates.

我在Stackoverflow上看到了很多关于它们的问题所有尝试的网络都在做同样的事情:
接受SSL证书。然而,这些答案似乎都不适用于我的问题,因为我没有弄乱 HTTPSUrlConnections

I saw a lot of toppics here on Stackoverflow and all over the web which are all trying do do the same: Accepting SSL Certificates. However None of these answers seem to apply to my Problem, as I'm not messing with HTTPSUrlConnections.

如果我正在请求代码通常看起来像这样(注释清除):

If I'm doing a request the code usually looks like this (commented for clearification):

//creates an HTTP-Post with an URL
HttpPost post = createBaseHttpPost();
//loads the request Data inside the httpPost
post.setEntity(getHttpPostEntity());
//appends some Headers like user-agend or Request UUIDs
appendHeaders(post);

HttpClient client = new DefaultHttpClient();
//mResponse is a custom Object which is returned 
//from the custom ResponseHandler(mResponseHandler) 
mResponse = client.execute(post, mResponseHandler);
return mResponse;

我读到我应该注入我自己的 TrustManager X509HostnameVerivier 。我创建它们是这样的:

I read that I should inject my own TrustManager and X509HostnameVerivier. I created them like this:

private static final TrustManager[] TRUST_ALL_CERTS = new TrustManager[]{
        new X509TrustManager() {

            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[]{};
            }

            public void checkServerTrusted(X509Certificate[] chain, String authType)
                    throws CertificateException {
            }

            public void checkClientTrusted(X509Certificate[] chain, String authType)
                    throws CertificateException {
            }
        }

    };

    private static X509HostnameVerifier ACCEPT_ALL_HOSTNAMES = 
            new X509HostnameVerifier() {

                public void verify(String host, String[] cns, String[] subjectAlts)
                        throws SSLException {
                }

                public void verify(String host, X509Certificate cert) throws SSLException {
                }

                public void verify(String host, SSLSocket ssl) throws IOException {
                }

                public boolean verify(String host, SSLSession session) {
                    return true;
                }
            };

如果我在请求中注入 HostnameVerifier 像这样(客户端是上面的DefaultHttpClient)

If I inject the HostnameVerifier inside my request like this (client is DefaultHttpClient from above)

SSLSocketFactory ssl = (SSLSocketFactory)client.getConnectionManager().getSchemeRegistry().getScheme("https").getSocketFactory();
ssl.setHostnameVerifier(ACCEPT_ALL_HOSTNAMES);

响应从主机名**不匹配变为错误请求。我想我必须设置TrustManager,但我无法在我的请求中设置它,因为我没有使用HttpsUrlConnections在我查找的任何地方提到。

the response turns from "hostname ** didn't match" to "Bad request". I guess I have to set the TrustManager, but I'm clueless where to set it inside my request, as I'm not using HttpsUrlConnections mentioned everywhere I looked it up.

推荐答案

不,它不会强制您禁用验证,它会强制您正确实施验证。 不要盲目接受所有证书。不,你的情况没有任何不同,你只需要信任Android默认不信任的证书。

No, it doesn't force you to disable validation, it forces you to implement validation properly. Do not blindly accept all certificates. And no, your case is not any different, you just need to trust a certificate that Android doesn't trust by default.

您正在使用HttpClient,因此设置信任管理器的API与 HttpsURLConnection 略有不同,但程序是相同的:

You are using HttpClient, so the APIs for setting the trust manager are somewhat different than HttpsURLConnection, but the procedure is the same:


  1. 加载带有受信任证书的密钥库文件(服务器的自签名证书)

  2. 使用它初始化 KeyStore

  3. 使用2中的 KeyStore 创建 SocketFactory

  4. 设置HTTP客户端库以在创建SSL套接字时使用它。

  1. Load a keystore file with trusted certificates (your server's self-signed certificates)
  2. Initialize a KeyStore with it.
  3. Create a SocketFactory using the KeyStore from 2.
  4. Set your HTTP client library to use it when creating SSL sockets.

这在Android的文档中有描述:http://developer.android.com/reference/org/apache/http/conn/ssl/SSLSocketFactory.html

This is described in Android's documentation: http://developer.android.com/reference/org/apache/http/conn/ssl/SSLSocketFactory.html

关于该主题的更详细的文章,展示了如何创建信任库文件: http://blog.crazybob.org/2010/02/android-trusting-ssl-certificates.html

A more detailed article on the subject, shows how to create the trust store file: http://blog.crazybob.org/2010/02/android-trusting-ssl-certificates.html

一些背景信息和示例代码: http://nelenkov.blogspot.com/2011/12/ using-custom-certificate-trust-store-on.html

Some background information and example code: http://nelenkov.blogspot.com/2011/12/using-custom-certificate-trust-store-on.html

这是初始化HttpClient所需的代码:

This is the code you need to initialize HttpClient:

KeyStore localTrustStore = KeyStore.getInstance("BKS");
InputStream in = getResources().openRawResource(R.raw.mytruststore);
localTrustStore.load(in, TRUSTSTORE_PASSWORD.toCharArray());

SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", PlainSocketFactory
                .getSocketFactory(), 80));
SSLSocketFactory sslSocketFactory = new SSLSocketFactory(localTrustStore);
schemeRegistry.register(new Scheme("https", sslSocketFactory, 443));
HttpParams params = new BasicHttpParams();
ClientConnectionManager cm = 
    new ThreadSafeClientConnManager(params, schemeRegistry);

HttpClient client = new DefaultHttpClient(cm, params); 

此时,您没有理由信任所有证书。如果你这样做,那一切都在你身上:))

At this point, you have no excuses for trusting all certificates. If you do, it all on you :)

这篇关于接受自签名SSL证书 - >在哪里设置默认的TrustManager的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆