全网整合营销服务商

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

免费咨询热线: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请求的简单封装与使用  # 会报  # 首页  # 过程中  # 自己的  # 公钥  # 并将  # 考虑到  # 自定义  # 为例  # 又不  # 会使  # 别忘了  # 将由  # 中都  # 工作原理  # 服务端  # 大家多多  # 一笔钱  # 字串  # 客户端 


相关文章: 如何快速搭建高效WAP手机网站吸引移动用户?  如何通过cPanel快速搭建网站?  如何通过山东自助建站平台快速注册域名?  建站主机数据库如何配置才能提升网站性能?  非常酷的网站设计制作软件,酷培ai教育官方网站?  Android滚轮选择时间控件使用详解  阿里云网站搭建费用解析:服务器价格与建站成本优化指南  C#如何使用XPathNavigator高效查询XML  宝塔新建站点报错如何解决?  如何选择高性价比服务器搭建个人网站?  制作网站的基本流程,设计网站的软件是什么?  专业商城网站制作公司有哪些,pi商城官网是哪个?  如何将凡科建站内容保存为本地文件?  如何用手机制作网站和网页,手机移动端的网站能制作成中英双语的吗?  北京制作网站的公司,北京铁路集团官方网站?  建设网站制作价格,怎样建立自己的公司网站?  C++如何将C风格字符串(char*)转换为std::string?(代码示例)  车管所网站制作流程,交警当场开简易程序处罚决定书,在交警网站查询不到怎么办?  如何在IIS中新建站点并配置端口与IP地址?  小建面朝正北,A点实际方位是否存在偏差?  详解jQuery中基本的动画方法  北京企业网站设计制作公司,北京铁路集团官方网站?  制作无缝贴图网站有哪些,3dmax无缝贴图怎么调?  北京网页设计制作网站有哪些,继续教育自动播放怎么设置?  如何基于云服务器快速搭建网站及云盘系统?  建站之星备案是否影响网站上线时间?  如何在香港免费服务器上快速搭建网站?  如何在阿里云部署织梦网站?  宝塔建站教程:一键部署配置流程与SEO优化实战指南  如何快速搭建高效可靠的建站解决方案?  公司网站的制作公司,企业网站制作基本流程有哪些?  交易网站制作流程,我想开通一个网站,注册一个交易网址,需要那些手续?  大型企业网站制作流程,做网站需要注册公司吗?  邀请函制作网站有哪些,有没有做年会邀请函的网站啊?在线制作,模板很多的那种?  如何快速搭建二级域名独立网站?  在线流程图制作网站手机版,谁能推荐几个好的CG原画资源网站么?  深圳网站制作培训,深圳哪些招聘网站比较好?  早安海报制作网站推荐大全,企业早安海报怎么每天更换?  如何基于云服务器快速搭建个人网站?  如何使用Golang安装API文档生成工具_快速生成接口文档  建站之星代理平台如何选择最佳方案?  制作网站的公司有哪些,做一个公司网站要多少钱?  ,sp开头的版面叫什么?  如何制作公司的网站链接,公司想做一个网站,一般需要花多少钱?  网站海报制作教学视频教程,有什么免费的高清可商用图片网站,用于海报设计?  如何通过老薛主机一键快速建站?  如何通过虚拟主机快速完成网站搭建?  如何选择CMS系统实现快速建站与SEO优化?  如何自定义建站之星模板颜色并下载新样式?  建站之星多图banner生成与模板自定义指南 

您的项目需求

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