Retrofit 2.0 + Okhttp 用HTTPS请求

先说明一下,我的是读取本地资源目录的证书,不是绕过验证,也不是校验服务端证书。

这是一个很简单的功能,确实。 但是没搞定之前还是难受得丫批。 百度上,简书上的方法都搜过了,用过了,没有用。最后发现是自己不会用(我就知道是这样子的!mmp) 写一篇文章记录一下。希望能够帮到(估计也没有人和我一样弱鸡了)。


正题开始

1.因为我们的H5,经常被插入小广告,于是就提议要搞HTTPS,然后申请去了几万,证书下来了(运维老哥给到我们手里)


证书文件

然后我看了网上的帖子后缀不一样,我又屁颠屁颠的跑去问了一下。 老哥给我解释了一下crt的全称,然后知道了有人叫crt,有人叫cer。然后我把证书复制到assets目录


assets目录

2.然后我开始了双屏CV操作,发现复制过来不能用。然后我朋友建议我去看看OkGo的项目。

OkGo 

下载下来看了一下,廖大神有写各种HTTPS的请求方式。真的很全了! 我用的是方法三。


OkGo HTTPS 请求方式

3.然后我直接就是把他的这个HttpsUtils方法复制出来了,然后在我自己的请求封装那里加上。

代码如下:


请求封装

Tips:之前有些帖子的证书是放在RAW文件夹里。然后这个地方脑残了一下,没注意getAssets这个方法。 

然后到这里就结束了。。。。吧?    我都打开网易云放歌了!   然后这个时候APP跑上来,请求出错。。等等。。

看看Logcat这个东西吧!   请求的地址还是http。 

这时候想到了点什么,加证书并不会自动给你加S,然后去请求的。

乖乖的把请求地址加上S。~ 


放歌吧! 


放歌请点击:Time


最后:廖大神的那个“优踢而丝”我放上来吧~

```

/**

* ================================================

* 作    者:jeasonlzy(廖子尧)Github地址:https://github.com/jeasonlzy

* 版    本:1.0

* 创建日期:16/9/11

* 描    述:Https相关的工具类

* 修订历史:

* ================================================

*/

public class HttpsUtils {

public static class SSLParams {

public SSLSocketFactorysSLSocketFactory;

        public X509TrustManagertrustManager;

    }

public static SSLParamsgetSslSocketFactory() {

return getSslSocketFactoryBase(null, null, null);

    }

/**

* https单向认证

* 可以额外配置信任服务端的证书策略,否则默认是按CA证书去验证的,若不是CA可信任的证书,则无法通过验证

*/

    public static SSLParamsgetSslSocketFactory(X509TrustManager trustManager) {

return getSslSocketFactoryBase(trustManager, null, null);

    }

/**

* https单向认证

* 用含有服务端公钥的证书校验服务端证书

*/

    public static SSLParamsgetSslSocketFactory(InputStream... certificates) {

return getSslSocketFactoryBase(null, null, null, certificates);

    }

/**

* https双向认证

* bksFile 和 password -> 客户端使用bks证书校验服务端证书

* certificates -> 用含有服务端公钥的证书校验服务端证书

*/

    public static SSLParamsgetSslSocketFactory(InputStream bksFile, String password, InputStream... certificates) {

return getSslSocketFactoryBase(null, bksFile, password, certificates);

    }

/**

* https双向认证

* bksFile 和 password -> 客户端使用bks证书校验服务端证书

* X509TrustManager -> 如果需要自己校验,那么可以自己实现相关校验,如果不需要自己校验,那么传null即可

*/

    public static SSLParamsgetSslSocketFactory(InputStream bksFile, String password, X509TrustManager trustManager) {

return getSslSocketFactoryBase(trustManager, bksFile, password);

    }

private static SSLParamsgetSslSocketFactoryBase(X509TrustManager trustManager, InputStream bksFile, String password, InputStream... certificates) {

SSLParams sslParams =new SSLParams();

        try {

KeyManager[] keyManagers =prepareKeyManager(bksFile, password);

            TrustManager[] trustManagers =prepareTrustManager(certificates);

            X509TrustManager manager;

            if (trustManager !=null) {

//优先使用用户自定义的TrustManager

                manager = trustManager;

            }else if (trustManagers !=null) {

//然后使用默认的TrustManager

                manager =chooseTrustManager(trustManagers);

            }else {

//否则使用不安全的TrustManager

                manager =UnSafeTrustManager;

            }

// 创建TLS类型的SSLContext对象, that uses our TrustManager

            SSLContext sslContext = SSLContext.getInstance("TLS");

            // 用上面得到的trustManagers初始化SSLContext,这样sslContext就会信任keyStore中的证书

// 第一个参数是授权的密钥管理器,用来授权验证,比如授权自签名的证书验证。第二个是被授权的证书管理器,用来验证服务器端的证书

            sslContext.init(keyManagers, new TrustManager[]{manager}, null);

            // 通过sslContext获取SSLSocketFactory对象

            sslParams.sSLSocketFactory = sslContext.getSocketFactory();

            sslParams.trustManager = manager;

            return sslParams;

        }catch (NoSuchAlgorithmException e) {

throw new AssertionError(e);

        }catch (KeyManagementException e) {

throw new AssertionError(e);

        }

}

private static KeyManager[]prepareKeyManager(InputStream bksFile, String password) {

try {

if (bksFile ==null || password ==null)return null;

            KeyStore clientKeyStore = KeyStore.getInstance("BKS");

            clientKeyStore.load(bksFile, password.toCharArray());

            KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());

            kmf.init(clientKeyStore, password.toCharArray());

            return kmf.getKeyManagers();

        }catch (Exception e) {

e.printStackTrace();

        }

return null;

    }

private static TrustManager[]prepareTrustManager(InputStream... certificates) {

if (certificates ==null || certificates.length <=0)return null;

        try {

CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");

            // 创建一个默认类型的KeyStore,存储我们信任的证书

            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());

            keyStore.load(null);

            int index =0;

            for (InputStream certStream : certificates) {

String certificateAlias = Integer.toString(index++);

                // 证书工厂根据证书文件的流生成证书 cert

                Certificate cert = certificateFactory.generateCertificate(certStream);

                // 将 cert 作为可信证书放入到keyStore中

                keyStore.setCertificateEntry(certificateAlias, cert);

                try {

if (certStream !=null) certStream.close();

                }catch (IOException e) {

e.printStackTrace();

                }

}

//我们创建一个默认类型的TrustManagerFactory

            TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());

            //用我们之前的keyStore实例初始化TrustManagerFactory,这样tmf就会信任keyStore中的证书

            tmf.init(keyStore);

            //通过tmf获取TrustManager数组,TrustManager也会信任keyStore中的证书

            return tmf.getTrustManagers();

        }catch (Exception e) {

e.printStackTrace();

        }

return null;

    }

private static X509TrustManagerchooseTrustManager(TrustManager[] trustManagers) {

for (TrustManager trustManager : trustManagers) {

if (trustManagerinstanceof X509TrustManager) {

return (X509TrustManager) trustManager;

            }

}

return null;

    }

/**

* 为了解决客户端不信任服务器数字证书的问题,网络上大部分的解决方案都是让客户端不对证书做任何检查,

* 这是一种有很大安全漏洞的办法

*/

    public static X509TrustManagerUnSafeTrustManager =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[]{};

        }

};

    /**

* 此类是用于主机名验证的基接口。 在握手期间,如果 URL 的主机名和服务器的标识主机名不匹配,

* 则验证机制可以回调此接口的实现程序来确定是否应该允许此连接。策略可以是基于证书的或依赖于其他验证方案。

* 当验证 URL 主机名使用的默认规则失败时使用这些回调。如果主机名是可接受的,则返回 true

*/

    public static HostnameVerifierUnSafeHostnameVerifier =new HostnameVerifier() {

@Override

        public boolean verify(String hostname, SSLSession session) {

return true;

        }

};

}

```

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,686评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,668评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,160评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,736评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,847评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,043评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,129评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,872评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,318评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,645评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,777评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,861评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,589评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,687评论 2 351

推荐阅读更多精彩内容