全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

Android使用OkHttp请求自签名的https网站的示例

前言

很多公司考虑到安全问题,项目中都采用https加密协议进行数据传输。但是一些公司又不想花一笔钱去CA申请证书,所以就采用自签名的证书。

OkHttp默认是可以访问通过CA认证的HTTPS链接,例如百度首页也是https链接(https://www.baidu.com/)。但是如果是你们公司自签名(即自己用keytool生成的证书,而不是采用通过CA认证的证书)的服务器,OkHttp是无法访问的,例如访问12306网站(https://kyfw.12306.cn/otn/),会报如下错误:

HTTPS的工作原理

HTTPS在传输数据之前需要客户端(浏览器)与服务端(网站)之间进行一次握手,在握手过程中将确立双方加密传输数据的密码信息。握手过程的简单描述如下:

  1. 浏览器将自己支持的一套加密算法、HASH算法发送给网站。
  2. 网站从中选出一组加密算法与HASH算法,并将自己的身份信息以证书的形式发回给浏览器。证书里面包含了网站地址,加密公钥,以及证书的颁发机构等信息。
  3. 浏览器获得网站证书之后,开始验证证书的合法性,如果证书信任,则生成一串随机数字作为通讯过程中对称加密的秘钥。然后取出证书中的公钥,将这串数字以及HASH的结果进行加密,然后发给网站。
  4. 网站接收浏览器发来的数据之后,通过私钥进行解密,然后HASH校验,如果一致,则使用浏览器发来的数字串使加密一段握手消息发给浏览器。
  5. 浏览器解密,并HASH校验,没有问题,则握手结束。接下来的传输过程将由之前浏览器生成的随机密码并利用对称加密算法进行加密。

握手过程中如果有任何错误,都会使加密连接断开,从而阻止了隐私信息的传输。

使用OKHTTP请求自签名的https服务器数据

以下我们使用12306网站为例

1. 首先去12306网站首页下载证书 http://www.12306.cn/

2. 将下载的证书srca.cer放到工程的assets文件夹下。

3. 添加HTTPS工具类

package com.alpha58.okhttp;

import android.content.Context;

import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.util.Arrays;
import java.util.Collection;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;

import okhttp3.OkHttpClient;

/**
 * Created by admin on 2017/03/12.
 */
public final class HTTPSUtils {
  private OkHttpClient client;

  public Context mContext;


  /**
   * 获取OkHttpClient实例
   * @return
   */
  public OkHttpClient getInstance()
  {
    return client;
  }

  /**
   * 初始化HTTPS,添加信任证书
   * @param context
   */
  public HTTPSUtils(Context context) {
    mContext = context;
    X509TrustManager trustManager;
    SSLSocketFactory sslSocketFactory;
    final InputStream inputStream;
    try {
      inputStream = mContext.getAssets().open("srca.cer"); // 得到证书的输入流
      try {

        trustManager = trustManagerForCertificates(inputStream);//以流的方式读入证书
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, new TrustManager[]{trustManager}, null);
        sslSocketFactory = sslContext.getSocketFactory();

      } catch (GeneralSecurityException e) {
        throw new RuntimeException(e);
      }

      client = new OkHttpClient.Builder()
          .sslSocketFactory(sslSocketFactory, trustManager)
          .build();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  /**
   * 以流的方式添加信任证书
   */
  /**
   * Returns a trust manager that trusts {@code certificates} and none other. HTTPS services whose
   * certificates have not been signed by these certificates will fail with a {@code
   * SSLHandshakeException}.
   * <p>
   * <p>This can be used to replace the host platform's built-in trusted certificates with a custom
   * set. This is useful in development where certificate authority-trusted certificates aren't
   * available. Or in production, to avoid reliance on third-party certificate authorities.
   * <p>
   * <p>
   * <h3>Warning: Customizing Trusted Certificates is Dangerous!</h3>
   * <p>
   * <p>Relying on your own trusted certificates limits your server team's ability to update their
   * TLS certificates. By installing a specific set of trusted certificates, you take on additional
   * operational complexity and limit your ability to migrate between certificate authorities. Do
   * not use custom trusted certificates in production without the blessing of your server's TLS
   * administrator.
   */
  private 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];
  }


  /**
   * 添加password
   * @param password
   * @return
   * @throws GeneralSecurityException
   */
  private 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 new AssertionError(e);
    }
  }


}

4.代码中请求

public void getHttpsHtml(View view) {
    Request request = new Request.Builder()
        .url("https://kyfw.12306.cn/otn/")
        .build();
    HTTPSUtils httpsUtils = new HTTPSUtils(this);
    httpsUtils.getInstance().newCall(request).enqueue(new Callback() {
      @Override
      public void onFailure(Call call, IOException e) {
        System.out.println("--------------onFailure--------------" + e.toString());
      }

      @Override
      public void onResponse(Call call, Response response) throws IOException {
        System.out.println("--------------onResponse--------------" + response.body().string());
      }
    });
  }
 

5. 最后能打印出这些信息就说明请求成功啦!

注意:别忘了加权限和依赖okhttp库

Demo地址:https://github.com/Alpha58/okhttps

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


# android  # https自签名请求  # https请求  # android使用https请求  # Android中使用OkHttp包处理HTTP的get和post请求的方法  # Android使用OkHttp发送post请求  # Android小知识之OkHttp的2种请求方式详解  # Android Okhttp请求查询购物车的实例代码  # Android基于OkHttpUtils网络请求的二次封装  # 详解Android中使用OkHttp发送HTTP的post请求的方法  # Android M(6.x)使用OkHttp包解析和发送JSON请求的教程  # 详解Android的OkHttp包编写异步HTTP请求调用的方法  # android实现okHttp的get和post请求的简单封装与使用  # 会报  # 首页  # 过程中  # 自己的  # 公钥  # 并将  # 考虑到  # 自定义  # 为例  # 又不  # 会使  # 别忘了  # 将由  # 中都  # 工作原理  # 服务端  # 大家多多  # 一笔钱  # 字串  # 客户端 


相关文章: 建站主机默认首页配置指南:核心功能与访问路径优化  专业企业网站设计制作公司,如何理解商贸企业的统一配送和分销网络建设?  javascript中的try catch异常捕获机制用法分析  浅谈Javascript中的Label语句  网页设计与网站制作内容,怎样注册网站?  Thinkphp 中 distinct 的用法解析  网页设计网站制作软件,microsoft office哪个可以创建网页?  建站上传速度慢?如何优化加速网站加载效率?  在线制作视频网站免费,都有哪些好的动漫网站?  建站主机核心功能解析:服务器选择与网站搭建流程指南  武汉网站如何制作,黄黄高铁武穴北站途经哪些村庄?  股票网站制作软件,网上股票怎么开户?  网站专业制作公司,网站编辑是做什么的?好做吗?工作前景如何?  建站10G流量真的够用吗?如何应对访问高峰?  开心动漫网站制作软件下载,十分开心动画为何停播?  如何获取上海专业网站定制建站电话?  如何选择高效便捷的WAP商城建站系统?  如何批量查询域名的建站时间记录?  网站制作费用多少钱,一个网站的运营,需要哪些费用?  如何选择长沙网站建站模板?H5响应式与品牌定制哪个更优?  建站主机CVM配置优化、SEO策略与性能提升指南  上海制作企业网站有哪些,上海有哪些网站可以让企业免费发布招聘信息?  如何快速上传自定义模板至建站之星?  山东云建站价格为何差异显著?  建站之星CMS五站合一模板配置与SEO优化指南  如何高效利用亚马逊云主机搭建企业网站?  贸易公司网站制作流程,出口贸易网站设计怎么做?  东莞市网站制作公司有哪些,东莞找工作用什么网站好?  攀枝花网站建设,攀枝花营业执照网上怎么年审?  建站主机选购指南:核心配置优化与品牌推荐方案  如何高效生成建站之星成品网站源码?  如何配置FTP站点权限与安全设置?  nginx修改上传文件大小限制的方法  建站之星2.7模板:企业网站建设与h5定制设计专题  表情包在线制作网站免费,表情包怎么弄?  建站主机解析:虚拟主机配置与服务器选择指南  ,交易猫的商品怎么发布到网站上去?  建站为何优先选择香港服务器?  专业网站设计制作公司,如何制作一个企业网站,建设网站的基本步骤有哪些?  制作网站哪家好,cc、.co、.cm哪个域名更适合做网站?  网站制作中优化长尾关键字挖掘的技巧,建一个视频网站需要多少钱?  音响网站制作视频教程,隆霸音响官方网站?  建站之星如何快速更换网站模板?  如何用景安虚拟主机手机版绑定域名建站?  黑客如何通过漏洞一步步攻陷网站服务器?  高防服务器:AI智能防御DDoS攻击与数据安全保障  建站之星备案是否影响网站上线时间?  广平建站公司哪家专业可靠?如何选择?  如何自定义建站之星网站的导航菜单样式?  如何构建满足综合性能需求的优质建站方案? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。