超级简单的retrofit使用自签名证书进行HTTPS请求的教程

来源:互联网 发布:淘宝页面背景图制作 编辑:程序博客网 时间:2024/05/20 05:24

1. 前言


HTTPS越来越成为主流,谷歌从 2017 年起,Chrome 浏览器将也会把采用 HTTP 协议的网站标记为「不安全」网站;苹果从 2017 年 iOS App 将强制使用 HTTPS;在国内热火朝天的小程序也要求必须使用 HTTPS 请求。那么为什么要使用HTTPS呢?首先说为什么使用https,简单点说就是为了防止数据传输过程中信息被窃取或偷换防止中间人攻击。 




2. 准备BKS证书,将证书放到项目raw目录下


准备.cer文件


可以跟后台开发人员直接拿,也可以直接在网站上下载

在网站上下载:

点击地址栏前面的小锁头,然后点击证书信息


点击详细信息->复制到文件



弹出证书向导,一直点下一步,然后选择导出路径,导出成功。







将.cer转换为.bks


首先要下载bouncycastle的JAR

http://repo2.maven.org/maven2/org/bouncycastle/bcprov-jdk16/1.46/bcprov-jdk16-1.46.jar


解压后在当前文件夹执行以下命令


keytool -importcert -v -trustcacerts -file “server.cert” -alias server_alias -keystore “server.bks” -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath “bcprov-jdk16-146.jar” -storetype BKS -storepass password


黑体字部分是你要修改的,其中 “server.cert”是原cer证书的名字,“server_alias”是别名,“server.bks”是转换后bks证书的名字,“password”是你证书的密码,下边会用到的。


成功后将.bks证书文件放到项目的raw目录下。



2. 获取SSLSocketFactory


这里是HTTPS证书认证的关键代码,注意password和设置keystore的bks类型一定不要搞错。


/** * 获取bks文件的sslsocketfactory * @param context * @return */public static SSLSocketFactory getSSLSocketFactory(Context context) {    final String CLIENT_TRUST_PASSWORD = "123456";//信任证书密码,该证书默认密码是123456    final String CLIENT_AGREEMENT = "TLS";//使用协议    final String CLIENT_TRUST_KEYSTORE = "BKS";    SSLContext sslContext = null;    try {        //取得SSL的SSLContext实例        sslContext = SSLContext.getInstance(CLIENT_AGREEMENT);        //取得TrustManagerFactory的X509密钥管理器实例        TrustManagerFactory trustManager = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());        //取得BKS密库实例        KeyStore tks = KeyStore.getInstance(CLIENT_TRUST_KEYSTORE);        InputStream is = context.getResources().openRawResource(R.raw.traint);        try {            tks.load(is, CLIENT_TRUST_PASSWORD.toCharArray());        } finally {            is.close();        }        //初始化密钥管理器        trustManager.init(tks);        //初始化SSLContext        sslContext.init(null, trustManager.getTrustManagers(), null);    } catch (Exception e) {        e.printStackTrace();        Log.e("SslContextFactory", e.getMessage());    }    return sslContext.getSocketFactory();}



3.配置retrofit


String baseUrl = "https://skyish-test.yunext.com";int[] certificates = {R.raw.traint};    String[] hostUrls = {baseUrl};    OkHttpClient client = new okhttp3.OkHttpClient.Builder()            .addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))            .sslSocketFactory(HTTPSUtils.getSSLSocketFactory(context))            //.hostnameVerifier(HTTPSUtils.getHostNameVerifier(hostUrls))             .readTimeout(10, TimeUnit.SECONDS)            .connectTimeout(10, TimeUnit.SECONDS)            .build();    Retrofit retrofit = new Retrofit.Builder().baseUrl(baseUrl)            .addConverterFactory(GsonConverterFactory.create())            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())            .client(client)            .build();

配置好这个就可以使用HTTPS连接了。



4.常见错误


SSLContext is not initialized.


原因:

1. 证书和证书密码不匹配。

2. 使用了错误的证书。证书类型不对,记得要用bks格式的证书文件。



阅读全文
0 0
原创粉丝点击