美文网首页Android HttpsNet安卓技巧
android开发之retrofit+okhttp+https+

android开发之retrofit+okhttp+https+

作者: kingjang | 来源:发表于2016-03-03 11:22 被阅读4705次

    由于开发中需要使用https与自有证书进行接口的请求。搜遍了google与baidu,出现最多的是“Android Https相关完全解析 当OkHttp遇到Https”这篇文章,结果我就依葫芦画瓢,复制了代码到项目中,并加入了cer文件,但最后结果还是请求失败,返回“javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.”。但是demo是可以正常访问的,百思不得其解。
    于是又经过了漫长的google、baidu,最后发现有文章《为你的安卓应用实现自签名的 SSL 证书》提到一句话:“安卓的 SSLContext 自带的TrustManager无法让本文示例中提到的自签名证书通过验证. 解决的办法是自己定义一个 TrustManager 类. 然后用这个类去验证自签名证书.”。犹如醍醐灌顶,于是自定义一个TrustManager类,果然,成功了!

    下面贴出代码,献给遇到同样问题的小伙伴们:

    自定义TrustManager类:

    private staticTrustManager[]getWrappedTrustManagers(TrustManager[] trustManagers) {
    
    finalX509TrustManager originalTrustManager = (X509TrustManager) trustManagers[0];
    
    return newTrustManager[]{
    
    newX509TrustManager() {
    
    publicX509Certificate[]getAcceptedIssuers() {
    
    returnoriginalTrustManager.getAcceptedIssuers();
    
    }
    
    public voidcheckClientTrusted(X509Certificate[] certs, String authType) {
    
    try{
    
    originalTrustManager.checkClientTrusted(certs, authType);
    
    }catch(CertificateException e) {
    
    e.printStackTrace();
    
    }
    
    }
    
    public voidcheckServerTrusted(X509Certificate[] certs, String authType) {
    
    try{
    
    originalTrustManager.checkServerTrusted(certs, authType);
    
    }catch(CertificateException e) {
    
    e.printStackTrace();
    
    }
    
    }
    
    }
    
    };
    
    }
    
    

    以下OKhttp是设置证书的方法:

    
    private staticSSLSocketFactorygetSSLSocketFactory_Certificate(Context context, String keyStoreType,intkeystoreResId)
    
    throwsCertificateException, KeyStoreException, IOException, NoSuchAlgorithmException, KeyManagementException {
    
    CertificateFactory cf = CertificateFactory.getInstance("X.509");
    
    InputStream caInput = context.getResources().openRawResource(keystoreResId);
    
    Certificate ca = cf.generateCertificate(caInput);
    
    caInput.close();
    
    if(keyStoreType ==null|| keyStoreType.length() ==0) {
    
    keyStoreType = KeyStore.getDefaultType();
    
    }
    
    KeyStore keyStore = KeyStore.getInstance(keyStoreType);
    
    keyStore.load(null,null);
    
    keyStore.setCertificateEntry("ca", ca);
    
    String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
    
    TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
    
    tmf.init(keyStore);
    
    TrustManager[] wrappedTrustManagers =getWrappedTrustManagers(tmf.getTrustManagers());
    
    SSLContext sslContext = SSLContext.getInstance("TLS");
    
    sslContext.init(null, wrappedTrustManagers,null);
    
    returnsslContext.getSocketFactory();
    
    }
    
    

    调用时把服务器生成的.cer证书放到raw目录下,然后调用:

    
    SSLSocketFactory sslSocketFactory =getSSLSocketFactory_Certificate(context,"BKS", R.raw.XXX);
    //new一个OkHttpClient
    OkHttpClient okHttpClient = new OkHttpClient();
    okHttpClient.setSslSocketFactory(sslSocketFactory);
    
    

    Retrofit构造的adapter使用自定义okHttpClient

    
    RestAdapter.Builder builder =newRestAdapter.Builder()
    
    .setEndpoint(serverUrl)
    
    .setClient(newOkClient(okHttpClient));
    
    

    第一次使用简书,多多指教

    相关文章

      网友评论

      • xbase:额,我发现还是会报exception,但是却可以返回结果
      • kingjang:各位抱歉,我已经很久没有做android开发了。demo已经不知去向
      • 449f2c214a46:第一次使用https,一脸茫然,能交流下么
      • 有酒和远方:楼主 能留个QQ交流一下么
      • 540c229b9e69:解决了,谢谢
      • UniqueMrZhang:求demo 楼主分享一下吧,qq347568193 分享打赏
      • 6e9430623298:同求demo,楼主分享下 qq 838524911
        UniqueMrZhang:@6e9430623298 楼主给你demo了没啊
      • EasonDev:请问有没有demo。我使用最新的okhttp有些方法已经没有了。
        唯爱_0834:这个很简单,改一下就好了啊
      • c4fedd0731ca:醍醐灌酒

      本文标题:android开发之retrofit+okhttp+https+

      本文链接:https://www.haomeiwen.com/subject/qxankttx.html