MicroKibaco / CrazyDailyQuestion

每日一问: 水滴石穿,聚沙成塔,坚持数月, 必有收获~
35 stars 1 forks source link

OKhhtp3 如何反抓包 #73

Open MicroKibaco opened 4 years ago

MicroKibaco commented 4 years ago

我们在看OKhttp源码的时候,其们可以看到TLS 握手的过程connectTls 方法

private void connectTls(ConnectionSpecSelector connectionSpecSelector) throws IOException {
    Address address = route.address();
    SSLSocketFactory sslSocketFactory = address.sslSocketFactory();
    boolean success = false;
    SSLSocket sslSocket = null;
    try {
        // 基于之前建立的Socket建立一个包装对象SSLSocket
        sslSocket = (SSLSocket) sslSocketFactory.createSocket(
                rawSocket, address.url().host(), address.url().port(), true /* autoClose */);
        // 对TLS相关信息进行配置
        ConnectionSpec connectionSpec = connectionSpecSelector.configureSecureSocket(sslSocket);
        if (connectionSpec.supportsTlsExtensions()) {
            Platform.get().configureTlsExtensions(
                    sslSocket, address.url().host(), address.protocols());
        }
        // 进行握手
        sslSocket.startHandshake();
        // 获取SSLSession
        SSLSession sslSocketSession = sslSocket.getSession();
        Handshake unverifiedHandshake = Handshake.get(sslSocketSession);
        // 验证证书对该主机是否有效
        if (!address.hostnameVerifier().verify(address.url().host(), sslSocketSession)) {
            List<Certificate> peerCertificates = unverifiedHandshake.peerCertificates();
            if (!peerCertificates.isEmpty()) {
                X509Certificate cert = (X509Certificate) peerCertificates.get(0);
                throw new SSLPeerUnverifiedException(
                        "Hostname " + address.url().host() + " not verified:"
                                + "\n    certificate: " + CertificatePinner.pin(cert)
                                + "\n    DN: " + cert.getSubjectDN().getName()
                                + "\n    subjectAltNames: " + OkHostnameVerifier.allSubjectAltNames(cert));
            } else {
                throw new SSLPeerUnverifiedException(
                        "Hostname " + address.url().host() + " not verified (no certificates)");
            }
        }
        address.certificatePinner().check(address.url().host(),
                unverifiedHandshake.peerCertificates());
        String maybeProtocol = connectionSpec.supportsTlsExtensions()
                ? Platform.get().getSelectedProtocol(sslSocket)
                : null;
        socket = sslSocket;
        // 获取source及sink
        source = Okio.buffer(Okio.source(socket));
        sink = Okio.buffer(Okio.sink(socket));
        handshake = unverifiedHandshake;
        protocol = maybeProtocol != null
                ? Protocol.get(maybeProtocol)
                : Protocol.HTTP_1_1;
        success = true;
    } catch (AssertionError e) {
        if (Util.isAndroidGetsocknameError(e)) throw new IOException(e);
        throw e;
    } finally {
        if (sslSocket != null) {
            Platform.get().afterHandshake(sslSocket);
        }
        if (!success) {
            closeQuietly(sslSocket);
        }
    }
}