java - Android Java SSL 套接字 - AllowAllHostNameVerifier

标签 java android sockets ssl

首先我想说我正在探索 SSL socket 的世界并且网上没有那么多资料,我已经浏览了 StackOverflow 上的大部分主题,但我仍然对 TrustManager 的概念感到困惑, keystore 、主机名 validator ... 所以我必须编写一个 Java 客户端(单向 SSL)以使用 SSL 连接某些服务器。 我正在制作三种行为,Android 的原生行为(我相信如果证书不受信任,它不会处理握手)。 一个朴素的,带有一个带有空 checkServerTrusted 函数的自定义 TrustManager。 现在我想使用 HostNameVerfier 来允许所有主机名。 但老实说,我有点迷路了,我已经搜索了好几天,但互联网上没有关于 android ssl 的好资料。 到目前为止,这是我的代码:

Naive custom TrustManager (empty checkServerTrusted)

SSLContext sslContext = SSLContext.getInstance("SSL");
TrustManager trustManagerNaive =    new X509TrustManager(){
        @Override
        public void checkClientTrusted(
                X509Certificate[] chain,
                String authType)
                throws CertificateException {
            // TODO Auto-generated method stub
        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public void checkServerTrusted(
                X509Certificate[] chain,
                String authType)
                throws CertificateException {
            // TODO Auto-generated method stub
        }
    };

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

SSLSocketFactory socketFactory = (SSLSocketFactory)sslContext.getSocketFactory();
SSLSocket socket = (SSLSocket)socketFactory.createSocket(host, Integer.parseInt(port_number_et.getText().toString()));

//Native Android behavior (does not accept any untrusted certificate)
SSLSocketFactory socketFactory = (SSLSocketFactory)SSLSocketFactory.getDefault();
SSLSocket socket = (SSLSocket)socketFactory.createSocket(host, Integer.parseInt(port_number_et.getText().toString()));                      

最佳答案

这是一个带有“不可信”证书的运行示例:

KeyStore keyStore = KeyStore.getInstance("BKS");
InputStream in = getContext().getAssets().open(Constants.KEYSTORE_FILENAME);
keyStore.load(in, Constants.KEYSTORE_PASSWORD);
in.close();

SSLSocketFactory socketFactory = new SSLSocketFactory(keyStore);
socketFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
registry.register(new Scheme("https", socketFactory, 443));
BasicHttpParams basicHttpParams = new BasicHttpParams();
HttpProtocolParams.setVersion(basicHttpParams, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(basicHttpParams, HTTP.UTF_8);
ThreadSafeClientConnManager ccm = new ThreadSafeClientConnManager(basicHttpParams, registry);

httpClient = new DefaultHttpClient(ccm, basicHttpParams);

一些解释:

  • 使用不受信任的证书创建 keystore
  • 加载 keystore 并在 SSLSocketFactory 中设置它
  • 将 hostnameVerifier 设置为 ALLOW_ALL_HOSTNAME_VERIFIER(因为证书不受信任)

然后您可以使用此 httpClient 进行 http 或 https 请求,如下所示:

httpClient.execute(httpGet, new BasicHttpContext());

关于java - Android Java SSL 套接字 - AllowAllHostNameVerifier,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29123106/

相关文章:

java - Java中socket编程从服务器向所有客户端发送数据

java - Android 应用程序客户端与 java 服务器的相互 TLS

java - 尝试将 EditText 表单提交到我的电子邮件时出错?没有应用程序可以执行此操作?

Android SlidingDrawer 不禁用按钮 'under' 抽屉

java - 解析jsoup中元素内的元素?

java - 如果服务器没有客户端 TCP 使用 java 请求的文件,如何显示错误消息

Java websocket 主机?

java - 输出流到字节[]

java - 在 Linux 上运行 Swing jar

Android 从 CSS 文件到字体的相对路径