使用okHttp

时间:2017-10-26 12:17:54

标签: android ssl ssl-certificate okhttp

此问题可能与How can I pin a certificate with Square OKHTTP?重复。但由于我不清楚,我再次提问。我必须将SSL证书附加到我的http客户端。我使用的是改装版2.2.0和okHttp版本3.6.0

我有.crt格式的证书。目前,我正在执行固定as shown here的证书。但我不知道它的适当与否。 以下是我的代码

       static void pinCertificate(Context context, OkHttpClient.Builder builder) {
            try {
                CertificateFactory cf = CertificateFactory.getInstance("X.509");
                InputStream cert = context.getResources().openRawResource(R.raw.certificate);
                Certificate ca;
                ca = cf.generateCertificate(cert);

                // creating a KeyStore containing our trusted CAs
                String keyStoreType = KeyStore.getDefaultType();
                KeyStore keyStore = KeyStore.getInstance(keyStoreType);
                keyStore.load(null, null);
                keyStore.setCertificateEntry("ca", ca);


                String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
                TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
                tmf.init(keyStore);


                SSLContext sslContext = SSLContext.getInstance("TLS");
                sslContext.init(null, tmf.getTrustManagers(), null);
                builder.sslSocketFactory(sslContext.getSocketFactory());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

使用okHttp固定.crt证书是否正确?我们如何测试它是否正确地进行了握手? 如果错误,任何人都可以显示示例代码来正确固定证书吗? 我看到了一些像https://medium.com/@develodroid/android-ssl-pinning-using-okhttp-ca1239065616

这样的样本和文档

但它与我实施的完全不同。他们没有使用crt文件。

如果有人可以分享关于证书固定的更好解释以及如何在okHttp中完成,那将非常有帮助。 提前致谢!!

3 个答案:

答案 0 :(得分:0)

这是证书固定。这是正确的方法。您可以在手机中安装 https 证书,使用 fiddler charles 进行测试。如果请求不成功,那么固定工作正常。通过禁用ssl固定来测试它。在这种情况下,请求将成功,您将能够在fiddler或charles中看到request + data

您还可以使用公钥锁定来锁定证书内的公钥

我已实施以下方式

            InputStream cert = context.getResources().openRawResource(R.raw.certificate);            
            CertificateFactory cf=CertificateFactory.getInstance("X.509", "BC");
            InputStream caInput = new BufferedInputStream(cert);
            X509Certificate ca = (X509Certificate) cf.generateCertificate(caInput);
            caInput.close();
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            keyStore.load(null);
            keyStore.setCertificateEntry(ca.getSubjectX500Principal().getName(), ca);
            KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");
            kmf.init(keyStore, null);
            KeyManager[] keyManagers = kmf.getKeyManagers();
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            tmf.init(keyStore);
            SSLContext context1 = SSLContext.getInstance("TLS");
            context1.init(keyManagers, tmf.getTrustManagers(), null);
            builder.sslSocketFactory(context1.getSocketFactory());

答案 1 :(得分:0)

你正在做的是正确的方式。我也是按照你实施的方式做到的。它很好用。快乐编码:)

答案 2 :(得分:0)

在此处查看示例https://square.github.io/okhttp/https/#certificate-pinning-kt-java

  private val client = OkHttpClient.Builder()
      .certificatePinner(
          CertificatePinner.Builder()
              .add("publicobject.com", "sha256/afwiKY3RxoMmLkuRW1l7QsPZTJPwDS2pdDROQjXw8ig=")
              .build())
      .build()

提醒:未经服务器TLS管理员的祝福,请勿使用证书固定!