1. Definition of HTTPS

When it comes to HTTPS, HTTP has to be mentioned. The biggest drawback of HTTP is plaintext transmission, which is easy to be tampered with during data transmission. Therefore, Netscape proposed HTTPS protocol. Ssl1.0 (transport layer security protocol) is an upgraded version of SSL3.0, which is used to encrypt communication between the server and client. SSL is deprecated in Android8.0 because of its unsecurity

2. Working principle

1.HTTPS initiates an SSL connection to port 443 of the server

2. The server sends the public key and digital certificate to the client

3. The client uses a random algorithm to generate a private key and encrypts the private key using the public key of the server to generate a symmetric key

4. The client sends the symmetric key to the server

5. The server encrypts data using symmetric keys

6. The client decrypts data using symmetric keys

The problem comes, in the second step, if someone intercepted the server to send a public key to the client, and then forged the server to communicate with the client, how can this be good, how to judge the public key is legitimate, digital certificate will come in handy

3. Digital certificate

Digital certificate is issued by the CA, authority CA a total of more than 100 of the world, a digital certificate contains a pair of asymmetric keys, a public key and a private key and awarded, issuer, such as information, the public key to transfer to the server public key encrypt, generate the cipher text, and then by the client’s private key to decrypt the digital certificate, Obtain the public key of the server and verify that the public key is valid

Take the browser www.baidu.com as an example to open the digital certificate by clicking the lock symbol next to the link

The certificate path displays the certificate chain. The root certificate has the highest rights in the order of root certificate >A>B>C. If www.baidu.com trusts the root certificate, it means that A, B, and C all trust the root certificate

You can view details about certificates such as public keys, public key parameters, and certificate policies. A mobile phone, as a client to access the network, also has a built-in certificate. Taking a Xiaomi mobile phone as an example, you can open the built-in CA certificate by setting – More Settings – System security – Encryption and credentials – Trusted credentials

system
personal
personal

4. Principle of packet capture

How do common packet capture tools, such as Fidder and Charles, parse HTTPS data from both clients and servers? In fact, the packet capture tool acts as a middleman agent. The packet capture works as follows:

  • Intercepts THE HTTPS request sent by the client and sends the request to the real server as the client
  • Intercept the return of the real server, pretend to be a real server, and send data to the client
  • The asymmetric secret key used to encrypt the server’s public key and the symmetric key used to encrypt the data were obtained

5. How to use HTTPS in Android and prevent packet capture

How to access the HTTPS in Android, Retrofit, actually OkHttp support HTTPS access project the introduction of network library, in order to * * implementation ‘com. Squareup. Okhttp3: OkHttp: 4.2.0’ * *, for example,

final OkHttpClient okHttpClient = new OkHttpClient.Builder().build();
final Request request = new Request.Builder()
        .url("https://www.baidu.com/robots.txt")
        .build();
final Response execute = okHttpClient.newCall(request).execute();
final String bodyStr = execute.body().string();
Log.d(TAG, bodyStr);
Copy the code

If you disable the CA certificate on the client, GlobalSign Root CA-R1 will cause an error if you do not trust the baidu server’s digital certificate

Caused by: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. This error can be avoided by manually placing GlobalSign Root CA-R1.cer into assets folder in your project. How do you refer to the integrated certificates in your project? through

SSLContext sslContext;
        try {
            InputStream inputStream = getAssets().open("");
            sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null.new TrustManager[]{OkhttpU.trustManagerForCertificates(inputStream)}, null);
            SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
            OkHttpClient okHttpClient = new OkHttpClient.Builder().sslSocketFactory(sslSocketFactory, OkhttpU.trustManagerForCertificates(inputStream)).build();
            final Request request = new Request.Builder()
                    .url("https://www.baidu.com/robots.txt")
                    .build();
            final Response execute = okHttpClient.newCall(request).execute();
            final String bodyStr = execute.body().string();
            Log.d(TAG, bodyStr);
        } catch (Exception e) {
            e.printStackTrace();
        }
Copy the code
public class OkhttpU {

    public static X509TrustManager trustManagerForCertificates(InputStream in)
            throws GeneralSecurityException {
        CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
        Collection<? extends Certificate> certificates = certificateFactory.generateCertificates(in);
        if (certificates.isEmpty()) {
            throw new IllegalArgumentException("expected non-empty set of trusted certificates");
        }

        // Put the certificates a key store.
        char[] password = "password".toCharArray(); // Any password will work.
        KeyStore keyStore = newEmptyKeyStore(password);
        int index = 0;
        for (Certificate certificate : certificates) {
            String certificateAlias = Integer.toString(index++);
            keyStore.setCertificateEntry(certificateAlias, certificate);
        }

        // Use it to build an X509 trust manager.
        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(
                KeyManagerFactory.getDefaultAlgorithm());
        keyManagerFactory.init(keyStore, password);
        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
                TrustManagerFactory.getDefaultAlgorithm());
        trustManagerFactory.init(keyStore);
        TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
        if(trustManagers.length ! =1| |! (trustManagers[0] instanceof X509TrustManager)) {
            throw new IllegalStateException("Unexpected default trust managers:"
                    + Arrays.toString(trustManagers));
        }
        return (X509TrustManager) trustManagers[0];
    }

    private static KeyStore newEmptyKeyStore(char[] password) throws GeneralSecurityException {
        try {
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            InputStream in = null; // By convention, 'null' creates an empty key store.
            keyStore.load(in, password);
            return keyStore;
        } catch (IOException e) {
            throw newAssertionError(e); }}}Copy the code

You can access HTTPS normally

SslSocketFactory can prevent packet capture by introducing a custom certificate and setting it to OkHttp. However,. Cer can be easily decompilated in assets. You can run the keytool -printcert-rfc-file srca.cer command in the JDK to export the character string and run the

OkHttpClientManager.getInstance()
                .setCertificates(new Buffer()
                        .writeUtf8(CER_STRING) //CER_STRING is a string constant everywhere
                        .inputStream());
Copy the code

Related articles

  • HTTPS theory and best practices in Android
  • An article looks at the relationship between HTTP, HTTPS, SSL/TSL
  • HTTPS is different from HTTP — TLS/SSL