OkHttp3.0 添加SSL证书信任

okhttp作为Android主要的网络请求框架之一,对okhttp的使用介绍网上资料也是一堆一堆的。

okhttp一个简单的网络请求:

Request request = new Request.Builder().get().url("https://www.baidu.com").build();

OkHttpClient.Builder builder = new OkHttpClient.Builder();

OkHttpClient client = builder.build();

 client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
            }
            @Override
            public void onResponse(Call call, Response response) throws IOException {
            }

        });

这段代码没啥技术难度。

在开发中,为了网络安全,一般会使用https,数字验证,加强网络安全。

okhttp提供了sslSocketFactory(SSLSocketFactory sslSocketFactory, X509TrustManager trustManager)方法,验证数字签名。

我先获取数字证书,这里使用百度数字证书。





获取到证书,把证书拷贝到asset文件下。

 private SSLSocketFactory getSSLSocketFactory() throws NoSuchAlgorithmException, KeyManagementException {
        SSLContext context = SSLContext.getInstance("TLS");
        TrustManager[] trustManagers = {new MyX509TrustManager()};
        context.init(null, trustManagers, new SecureRandom());
        return context.getSocketFactory();
    }
    private class MyX509TrustManager implements X509TrustManager {

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

        }

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            if (chain == null) {
                throw new CertificateException("checkServerTrusted: X509Certificate array is null");
            }
            if (chain.length < 1) {
                throw new CertificateException("checkServerTrusted: X509Certificate is empty");
            }
            if (!(null != authType && authType.equals("ECDHE_RSA"))) {
                throw new CertificateException("checkServerTrusted: AuthType is not ECDHE_RSA");
            }

            //检查所有证书
            try {
                TrustManagerFactory factory = TrustManagerFactory.getInstance("X509");
                factory.init((KeyStore) null);
                for (TrustManager trustManager : factory.getTrustManagers()) {
                    ((X509TrustManager) trustManager).checkServerTrusted(chain, authType);
                }
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (KeyStoreException e) {
                e.printStackTrace();
            }

            //获取本地证书中的信息
            String clientEncoded = "";
            String clientSubject = "";
            String clientIssUser = "";
            try {
                CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
                InputStream inputStream = getAssets().open("baidu.cer");
                X509Certificate clientCertificate = (X509Certificate) certificateFactory.generateCertificate(inputStream);
                clientEncoded = new BigInteger(1, clientCertificate.getPublicKey().getEncoded()).toString(16);
                clientSubject = clientCertificate.getSubjectDN().getName();
                clientIssUser = clientCertificate.getIssuerDN().getName();
            } catch (IOException e) {
                e.printStackTrace();
            }

            //获取网络中的证书信息
            X509Certificate certificate = chain[0];
            PublicKey publicKey = certificate.getPublicKey();
            String serverEncoded = new BigInteger(1, publicKey.getEncoded()).toString(16);

            if (!clientEncoded.equals(serverEncoded)) {
                throw new CertificateException("server's PublicKey is not equals to client's PublicKey");
            }
            String subject = certificate.getSubjectDN().getName();
            if (!clientSubject.equals(subject)) {
                throw new CertificateException("server's subject is not equals to client's subject");
            }
            String issuser = certificate.getIssuerDN().getName();
            if (!clientIssUser.equals(issuser)) {
                throw new CertificateException("server's issuser is not equals to client's issuser");
            }
        }

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

代码中使用 builder.sslSocketFactory(getSSLSocketFactory(), new MyX509TrustManager())启用数字证书验证

转载请说明出处:https://mp.csdn.net/postedit/80245887

源代码传送门

  • 5
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
要在OkHttp3信任所有证书,可以通过自定义信任管理器来实现。以下是一个示例代码: ```java // 创建信任管理器,以信任所有证书 TrustManager[] trustAllCerts = new TrustManager[] { 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[0]; } } }; // 创建SSL上下文,并设置信任管理器 SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, trustAllCerts, new SecureRandom()); // 创建OkHttpClient实例,并配置信任所有证书SSL socket工厂 OkHttpClient client = new OkHttpClient.Builder() .sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) trustAllCerts[0]) .hostnameVerifier((hostname, session) -> true) .build(); // 使用client发送请求 Request request = new Request.Builder() .url("https://example.com") .build(); Response response = client.newCall(request).execute(); ``` 上述代码中,我们创建了一个自定义的信任管理器,其中的 `checkClientTrusted` 和 `checkServerTrusted` 方法为空实现,即不进行证书验证,`getAcceptedIssuers` 方法返回一个空的证书数组。然后,我们创建了一个SSL上下文,并使用自定义的信任管理器进行初始化。接下来,我们创建了一个OkHttpClient实例,并使用自定义的SSL socket工厂和主机验证器配置了该实例。最后,我们可以使用这个client实例发送请求。 请注意,信任所有证书可能会导致安全风险,请谨慎使用。在生产环境中,建议根据实际情况配置信任证书

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值