OkHttp证书校验

1、demo演示

通过OkHttp拉取网页信息,为OkHttp设置证书验证
在这里插入图片描述

以知网为例,https://www.cnki.net/
在这里插入图片描述

文件夹中未放置知网证书时,
在这里插入图片描述
文件夹中放置了知网证书时,
在这里插入图片描述
在这里插入图片描述

2、代码

依赖

//BindView
implementation 'com.jakewharton:butterknife:10.2.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1'

//okHttp
implementation 'com.squareup.okhttp3:okhttp:3.10.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.4.1'

权限

<uses-permission android:name="android.permission.INTERNET" />

1)数据处理

  • OkHttpManager
public class OkHttpManager {
    
    public static final String TAG = "OkHttpManager";

    /**
     * CERT_ALIAS  证书别名
     */
    public static final String CERT_ALIAS = "NCB";

    /**
     * CONNECT_TIME_OUT  连接超时
     * READ_TIME_OUT     读超时
     * WRITE_TIME_OUT    写超时
     */
    public static final int CONNECT_TIME_OUT = 75;
    public static final int READ_TIME_OUT = 75;
    public static final int WRITE_TIME_OUT = 75;

    /**
     * instance 单例
     * INSTANCE_LOCK 互斥锁
     */
    private static OkHttpManager instance = null;
    private static final Object INSTANCE_LOCK = new Object();


    /**
     * 获取单例
     *
     * @return
     */
    public static OkHttpManager getInstance() {
        if (instance == null) {
            synchronized (INSTANCE_LOCK) {
                if (instance == null) {
                    instance = new OkHttpManager();
                }
            }
        }
        return instance;
    }


    /**
     * 获取本地证书
     *
     * @return
     */
    private ArrayList<Certificate> getCertificatesFromAssets(Context context) {
        ArrayList<Certificate> certificates = new ArrayList<>();
        try {
            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
            String certPath = "certs";
            AssetManager am = context.getAssets();
            String[] list = am.list(certPath);
            for (int i = 0; i < list.length; i++) {
                certificates.add(certificateFactory.generateCertificate(am.open(certPath + "/" + list[i])));
                Log.i(TAG, "cer name:" + certPath + "/" + list[i]);
            }
            return certificates;
        } catch (Exception e) {
            e.printStackTrace();
            Log.e(TAG, e.getMessage());
        }
        return null;
    }


    /**
     * 获取含证书校验功能的 OkHttpClientBuilder
     *
     * @param context
     * @return
     */
    public OkHttpClient.Builder getOkHttpClientBuilderWithCerts(Context context) {
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        try {
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            keyStore.load(null);

            ArrayList<Certificate> localCerts = getCertificatesFromAssets(context);
            for (int i = 0; i < localCerts.size(); i++) {
                keyStore.setCertificateEntry(CERT_ALIAS + i, localCerts.get(i));
            }

            SSLContext sslContext = SSLContext.getInstance("TLS");
            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init(keyStore);
            sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());
            SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
            final X509TrustManager 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];
                }
            };
            builder.sslSocketFactory(sslSocketFactory, trustManager);

            HostnameVerifier hostnameVerifier = new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            };
            builder.hostnameVerifier(hostnameVerifier);

            builder.connectTimeout(CONNECT_TIME_OUT, TimeUnit.SECONDS)
                    .readTimeout(READ_TIME_OUT, TimeUnit.SECONDS)
                    .writeTimeout(WRITE_TIME_OUT, TimeUnit.SECONDS);


            return builder;
        } catch (Exception e) {
            e.printStackTrace();
            Log.e(TAG, e.getMessage());
        }
        return null;
    }
}
  • DataManager
/**
 * @description 数据处理层
 */
public class DataManager {

    /**
     * 从服务器获取数据
     *
     * @param url          请求url
     * @param dataCallback 回调
     */
    public static void getDataFromServer(Context context, String url, final DataCallback dataCallback) {
        OkHttpClient.Builder builder = OkHttpManager.getInstance().getOkHttpClientBuilderWithCerts(context);
        Request request = new Request.Builder().url(url).build();
        builder.build().newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                dataCallback.getDataFailed(e.getMessage());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                InputStream inputStream = response.body().byteStream();
                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
                StringBuilder stringBuilder = new StringBuilder();
                String line = "";
                while ((line = reader.readLine()) != null) {
                    stringBuilder.append(line);
                }
                dataCallback.getDataSuccess(stringBuilder.toString());
            }
        });
    }
}
  • ViewModel
public class DataViewModel extends ViewModel {

    /**
     * liveData  LiveData
     */
    private MutableLiveData<String> liveData;

    /**
     * 构造函数
     */
    public DataViewModel() {
        liveData = new MutableLiveData<>();
    }

    /**
     * 获取 LiveData
     *
     * @return
     */
    public MutableLiveData<String> getLiveData() {
        return liveData;
    }

    /**
     * 获取网站数据
     *
     * @param context
     * @param url
     */
    public void getDataFromServer(Context context, String url) {
        DataManager.getDataFromServer(context, url, new DataCallback() {
            @Override
            public void getDataSuccess(String data) {
                liveData.postValue("data : \n\n" + data);
            }

            @Override
            public void getDataFailed(String errMsg) {
                liveData.postValue("error message \n\n: " + errMsg);
            }
        });
    }
}

2)界面布局

  • BaseActivity
abstract public class BaseActivity extends AppCompatActivity {

    private Unbinder unbinder = null;


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(getLayoutId());
        unbinder = ButterKnife.bind(this);
        init();
    }

    abstract protected int getLayoutId();

    abstract protected void init();

    protected BaseActivity getActivity() {
        return this;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (unbinder != null) {
            unbinder.unbind();
        }
    }
}
  • Activity
public class OkHttpActivity extends BaseActivity {

    //知网
    public static final String TEST_URL = "https://www.cnki.net/";

    private DataViewModel dataViewModel;

    @BindView(R.id.id_btn_get_data)
    TextView btnGetData;
    @BindView(R.id.id_tv_show_data)
    TextView tvShowData;


    @Override
    protected int getLayoutId() {
        return R.layout.act_ok_http;
    }

    @Override
    protected void init() {
        dataViewModel = new ViewModelProvider(this, new ViewModelProvider.NewInstanceFactory()).get(DataViewModel.class);
        dataViewModel.getLiveData().observe(this, new Observer<String>() {
            @Override
            public void onChanged(String s) {
                tvShowData.setText(s);
            }
        });

        tvShowData.setMovementMethod(ScrollingMovementMethod.getInstance());
        btnGetData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dataViewModel.getDataFromServer(getActivity(), TEST_URL);
            }
        });
    }
}
  • layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/id_btn_get_data"
        style="@style/ButtonNormalStyle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="20dp"
        android:background="@color/black"
        android:text="get data" />


    <TextView
        android:id="@+id/id_tv_show_data"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="20dp"
        android:fadeScrollbars="false"
        android:scrollbarSize="10dp"
        android:scrollbars="vertical"
        android:text="result"
        android:textSize="30dp" />

</LinearLayout>

3、使用谷歌浏览器下载网站证书

以知网为例:https://www.cnki.net/

1、点击“锁”图标
在这里插入图片描述
2、点击证书
在这里插入图片描述
3、详细信息 -> 复制文件
在这里插入图片描述
4、下一页
在这里插入图片描述
5、保存
在这里插入图片描述
6、完成
在这里插入图片描述
在这里插入图片描述

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

KillerNoBlood

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值