握手失败使用 okHttp 但使用 HttpURLConnection

Vai*_*ari 1 ssl android httpurlconnection okhttp

我正在尝试向服务器发送 get 请求(发送 get 请求进行测试,实际上我需要向同一台服务器发送一个 post 请求。如果 get 有效,post 将起作用)

服务器链接是 https://bits-bosm.org/2017/registrations/signup/

问题是当我使用 okHttp 发送请求时,我收到一个失败响应,说握手失败。

这是我用来使用 okHttp 发送请求的代码(在 kotlin 中)

val request = Request.Builder()
            .url("https://bits-bosm.org/2017/registrations/signup/")
            .build()

    okHttpClient.newCall(request).enqueue(object : Callback {
        override fun onFailure(call: Call?, e: IOException?) {
            val mMessage = e?.message?.toString()
            Log.w("failure Response", mMessage)
        }

        override fun onResponse(call: Call?, response: Response?) {
            val mMessage = response?.body()?.string()
            Log.e("Message", mMessage)
        }
    })
Run Code Online (Sandbox Code Playgroud)

但是如果我使用 HttpUrlConnection 将获取请求发送到同一台服务器,我会得到响应。

这是相同的代码(java)

private static final String USER_AGENT = "Mozilla/5.0";

private static final String GET_URL = "https://bits-bosm.org/2017/registrations/signup/";



static void sendGET() throws IOException {
    URL obj = new URL(GET_URL);
    HttpURLConnection con = (HttpURLConnection) obj.openConnection();
    con.setRequestMethod("GET");
    con.setRequestProperty("User-Agent", USER_AGENT);
    int responseCode = con.getResponseCode();
    System.out.println("GET Response Code :: " + responseCode);
    if (responseCode == HttpURLConnection.HTTP_OK) { // success
        BufferedReader in = new BufferedReader(new InputStreamReader(
                con.getInputStream()));
        String inputLine;
        StringBuffer response = new StringBuffer();

        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();

        // print result
        Log.e("Result", response.toString());
    } else {
        System.out.println("GET request not worked");
    }

}
Run Code Online (Sandbox Code Playgroud)

根据我在互联网上搜索的内容以及我可以推断出的内容,问题是该站点是使用自证书签名的,而 okHttp 不允许使用它们。我什至尝试使用我在 Internet 上找到的代码片段,这些代码片段不检查证书(自定义 SSLSocketFactory)和其他一些解决方案,但它们都不起作用。此外,我现在也不关心安全性,我只想让它发挥作用。但我无法访问后端,也无法更改/删除 ssl 安全性。

怎么做才能让它发挥作用?有什么我想念的吗?

小智 5

这是广泛用作解决方法的不安全 OkHttpClient。

不要在生产中使用它,它仅用于开发目的。

import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import okhttp3.OkHttpClient;

public class Http {

    private final static String SSL = "SSL";

    private static OkHttpClient InsecureHttpClient;

    public static OkHttpClient client () {
        if (InsecureHttpClient == null) {
            try {
                InsecureHttpClient = insecureOkHttpClient ();
            } catch (Exception e) {
                e.printStackTrace ();
            }
        }

        return InsecureHttpClient;
    }

    private static OkHttpClient insecureOkHttpClient () throws Exception {
        TrustManager [] trustAllCerts       = new TrustManager [] { trustManager () };

        SSLContext sslContext               = SSLContext.getInstance (SSL);
        sslContext.init (null, trustAllCerts, new SecureRandom ());

        SSLSocketFactory sslSocketFactory   = sslContext.getSocketFactory ();

        OkHttpClient.Builder builder        = new OkHttpClient.Builder ();
        builder.sslSocketFactory (sslSocketFactory, (X509TrustManager)trustAllCerts [0]);
        builder.hostnameVerifier (hostnameVerifier ());

        return builder.build ();
    }

    private static TrustManager trustManager () {
        return new X509TrustManager () {

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

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

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

    private static HostnameVerifier hostnameVerifier () {
        return new HostnameVerifier () {

            @Override
            public boolean verify (String hostname, SSLSession session) {
                return true;
            }
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,您显然会像下面的测试代码一样使用上面的客户端:(顺便说一句,它适用于您的网址)

final Request request = new Request.Builder ()
    .url ("https://bits-bosm.org/2017/registrations/signup/")
    .get ()
    .addHeader ("Accept", "text/html")
    .build ();

final OkHttpClient httpClient = Http.client ();

new Thread (new Runnable () {

    @Override
    public void run () {
        try {
            Response response = httpClient.newCall (request).execute ();

            Logger.error (MainActivity.class.getSimpleName () + " --> Http Response", response.body ().string ());

        } catch (IOException e) {
            e.printStackTrace ();
        }
    }

}).start ();
Run Code Online (Sandbox Code Playgroud)