Communication between the Android Https _ client-way authentication check prevent middle attack

Disclaimer: This blog is mainly recorded some of the problems encountered by study notes and solutions, please indicate the source! https://blog.csdn.net/u010982507/article/details/85266096

HTTPS is introduced to solve the three problems caused by HTTP:

  • HTTP is transmitted in the clear, easily stolen data, so the data to be encrypted to prevent data theft midway
  • Identity authentication server, make sure to send data to the correct server
  • Maintain data integrity, prevent data from being altered in transit, such as man in the middle attack
    , this chapter is mainly about how to use OkHttp or HttpUrlConnection to achieve access to self-certificate.

Setting certificate verification

In the previous blog wrote how to bypass the certificate access, it is unsafe access, vulnerable middle attack, so the client needs to do two-way certificate verification, to ensure the legitimacy of the client.

private static SSLSocketFactory setCertificates(InputStream... certificates) {
   try {
       CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
       KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
       keyStore.load(null);
       int index = 0;
       for (InputStream certificate : certificates) {
           String certificateAlias = Integer.toString(index++);
           keyStore.setCertificateEntry(certificateAlias, certificateFactory.generateCertificate(certificate));
           if (certificate != null) {
               certificate.close();
           }
       }
       SSLContext sslContext = SSLContext.getInstance("TLS");
       TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
       trustManagerFactory.init(keyStore);
       sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());
       return sslContext.getSocketFactory();
   } catch (Exception e) {
       e.printStackTrace();
       return null;
   }
}

Set the domain name check

The domain verification need to set a trustHosts array that matches a domain name is currently accessing this array, it can return true, otherwise false.

//获取HostnameVerifier
public static HostnameVerifier getHostnameVerifier(final JSONArray trustHosts) {
    HostnameVerifier hostnameVerifier = new HostnameVerifier() {
        @Override
        public boolean verify(String host, SSLSession sslSession) {
            if (trustHosts == null || trustHosts.length() == 0) {
                return false;
            }
            try {
                for (int i = 0; i < trustHosts.length(); i++) {
                    String trustHost = trustHosts.getString(i);
                    if (host.equalsIgnoreCase(trustHost)) {
                        return true;
                    }
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
            return false;
        }
    };
    return hostnameVerifier;
}

Call Interface

//获取这个SSLSocketFactory
public static SSLSocketFactory getSSLSocketFactory(InputStream cerIn) {
    try {
        SSLSocketFactory factory = setCertificates(cerIn);
        return factory;
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

OkHttp set a trust certificate

JSONArray trustHosts= new JSONArray();
jsonArray.put("192.169.15.110");
jsonArray.put("192.169.15.111");
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.sslSocketFactory(SSLSocketCert.getSSLSocketFactory(context.getAssets().open("jetty.crt")));
builder.hostnameVerifier(SSLSocketCert.getHostnameVerifier(trustHosts));

HttpURLConnection set a trust certificate

JSONArray trustHosts= new JSONArray();
jsonArray.put("192.169.15.110");
jsonArray.put("192.169.15.111");
URL url = new URL(fileUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
((HttpsURLConnection) conn).setSSLSocketFactory(SSLSocketCert.getSSLSocketFactory(context.getAssets().open("jetty.crt")));
((HttpsURLConnection) conn).setHostnameVerifier(SSLSocketCert.getHostnameVerifier(trustHosts));

Use a certificate string

The above is the certificate into the Android project assetsunder, we can also guide out into the contents of the certificate program

private String CER_STR = "-----BEGIN CERTIFICATE-----\n" +
          "MIICmjCCAgOgAwIBAgIIbyZr5/jKH6QwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCQ04xKTAn\n" +
          "BgNVBAoTIFNpbm9yYWlsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRTUkNBMB4X\n" +
          "DTA5MDUyNTA2NTYwMFoXDTI5MDUyMDA2NTYwMFowRzELMAkGA1UEBhMCQ04xKTAnBgNVBAoTIFNp\n" +
          "bm9yYWlsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRTUkNBMIGfMA0GCSqGSIb3\n" +
          "DQEBAQUAA4GNADCBiQKBgQDMpbNeb34p0GvLkZ6t72/OOba4mX2K/eZRWFfnuk8e5jKDH+9BgCb2\n" +
          "9bSotqPqTbxXWPxIOz8EjyUO3bfR5pQ8ovNTOlks2rS5BdMhoi4sUjCKi5ELiqtyww/XgY5iFqv6\n" +
          "D4Pw9QvOUcdRVSbPWo1DwMmH75It6pk/rARIFHEjWwIDAQABo4GOMIGLMB8GA1UdIwQYMBaAFHle\n" +
          "tne34lKDQ+3HUYhMY4UsAENYMAwGA1UdEwQFMAMBAf8wLgYDVR0fBCcwJTAjoCGgH4YdaHR0cDov\n" +
          "LzE5Mi4xNjguOS4xNDkvY3JsMS5jcmwwCwYDVR0PBAQDAgH+MB0GA1UdDgQWBBR5XrZ3t+JSg0Pt\n" +
          "x1GITGOFLABDWDANBgkqhkiG9w0BAQUFAAOBgQDGrAm2U/of1LbOnG2bnnQtgcVaBXiVJF8LKPaV\n" +
          "23XQ96HU8xfgSZMJS6U00WHAI7zp0q208RSUft9wDq9ee///VOhzR6Tebg9QfyPSohkBrhXQenvQ\n" +
          "og555S+C3eJAAVeNCTeMS3N/M5hzBRJAoffn3qoYdAO1Q8bTguOi+2849A==\n" +
          "-----END CERTIFICATE-----";

Then call

JSONArray trustHosts= new JSONArray();
jsonArray.put("192.169.15.110");
jsonArray.put("192.169.15.111");
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.sslSocketFactory(SSLSocketCert.getSSLSocketFactory(new Buffer().writeUtf8(CER_STR).inputStream()));
builder.hostnameVerifier(SSLSocketCert.getHostnameVerifier(trustHosts));

Tools upload address
https://download.csdn.net/download/u010982507/10905059
study reference
https://blog.csdn.net/lmj623565791/article/details/48129405

Guess you like

Origin blog.csdn.net/u010982507/article/details/85266096