Android开发 - Retrofit 2 使用自签名的HTTPS证书进行API请求

简介:

为了确保数据传输的安全,现在越来越多的应用使用Https的方式来进行数据传输,使用https有很多有点,比如:

  • HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全,可防止数据在传输过程中不被窃取、改变,确保数据的完整性。
  • HTTPS是现行架构下最安全的解决方案,虽然不是绝对安全,但它大幅增加了中间人攻击的成本。

但是即使使用HTTPS有很多有点,但是购买一个认证的HTTPS证书却价格不菲,增加了初创企业和小团队的开发成本。而且如上面所说,使用HTTPS并非绝对的安全,传输的数据并非没有办法获取到,我的之前一篇博客所使用的方法已成功截取HTTPS的数据传输。有兴趣的可以参考:使用Charles对Android App的https请求进行抓包

为了节约成本,我们可以选择使用自签名的HTTPS。
这种方式我们可以自己生成证书,不需要购买证书,但是使用这种方式的域名如果在浏览器中访问的话,会有一个不安全的标识。但是如果用在客户端上,就不会有这个问题,现在一些应用商店也要求APP上架时需要使用HTTPS的网络请求(比如AppStore),使用这种自签名的HTTPS同样也能过审。

本文我们介绍在Android上使用网络请求框架Retrofit 2来请求自签名的API,关于如何生成HTTPS证书,我们将在另一篇博客中进行说明,敬请期待。或者您可以自行查找相关资料。

配置证书

比如我们生成的SLL证书文件为"api_ssl_debug.cer",我们将其放到assets目录下。这样在配置Retrofit的时候就可以读取该证书并用于API请求中。

配置Retrofit

本节我们介绍SSL证书在Retrofit中的配置,首先我们要定义两个方法用来读取证书,然后讲该证书用于Retrofit中。

  1. 读取证书内容到KeyStore中
    private static KeyStore getKeyStore(String fileName) {
        KeyStore keyStore = null;
        try {
            AssetManager assetManager = Utils.getApp().getAssets();
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            InputStream caInput = assetManager.open(fileName);
            Certificate ca;
            try {
                ca = cf.generateCertificate(caInput);
                Log.d("SslUtils", "ca=" + ((X509Certificate) ca).getSubjectDN());
            } finally {
                caInput.close();
            }

            String keyStoreType = KeyStore.getDefaultType();
            keyStore = KeyStore.getInstance(keyStoreType);
            keyStore.load(null, null);
            keyStore.setCertificateEntry("ca", ca);
        } catch (Exception e) {
            Log.e("SslUtils", "Error during getting keystore", e);
        }
        return keyStore;
    }
  1. 生成SSLContext以便用于Retrofit的配置中
    public static SSLContext getSslContextForCertificateFile(String fileName) {
        try {
            KeyStore keyStore = SslUtils.getKeyStore(fileName);
            SSLContext sslContext = SSLContext.getInstance("SSL");
            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init(keyStore);
            sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());
            return sslContext;
        } catch (Exception e) {
            String msg = "Error during creating SslContext for certificate from assets";
            Log.e("SslUtils", msg, e);
            throw new RuntimeException(msg);
        }
    }
  1. 配置Retrofit
SSLContext sslContext = SslUtils.getSslContextForCertificateFile("api_ssl_debug.cer");

TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
                TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init((KeyStore) null);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
    throw new IllegalStateException("Unexpected default trust managers:"
                    + Arrays.toString(trustManagers));
}
X509TrustManager trustManager = (X509TrustManager) trustManagers[0];

OkHttpClient.Builder builder = new OkHttpClient.Builder()
                ...
                .sslSocketFactory(sslContext.getSocketFactory(), trustManager)
                .hostnameVerifier((hostname, session) -> true)
                ...
                
mRetrofit = new Retrofit.Builder()
                ...
                build();

以上的省略号为Retrofit的其它配置,可以根据工程需要进行配置。

总结

至此,使用Retrofit就可以进行自签名的HTTPS的网络请求了,当然,服务器端的API配置也需要进行HTTPS的配置,我将在服务端相关的博客进行介绍,还有一点,如果请求的域名指定了端口,要将端口设置为443。如果没有指定端口,请求时也会自动走443端口。

本文原始地址,如有更多疑问,请参考我的其它Android相关博客:我的博客地址

目录
相关文章
|
14天前
|
JSON API 数据格式
获取商品详情API的请求格式是什么
获取商品详情API的请求格式通常依赖于特定的电商平台或服务提供商,但一般遵循类似的结构。以下是一个概括性的说明,以及针对几个主流电商平台的示例:
|
2月前
|
缓存 监控 API
抖音抖店 API 请求获取宝贝详情数据的调用频率限制如何调整?
抖音抖店API请求获取宝贝详情数据的调用频率受限,需遵循平台规则。开发者可通过提升账号等级、申请更高配额、优化业务逻辑(如缓存数据、异步处理、批量请求)及监控调整等方式来应对。
|
2月前
|
缓存 负载均衡 API
抖音抖店API请求获取宝贝详情数据、原价、销量、主图等参数可支持高并发调用接入演示
这是一个使用Python编写的示例代码,用于从抖音抖店API获取商品详情,包括原价、销量和主图等信息。示例展示了如何构建请求、处理响应及提取所需数据。针对高并发场景,建议采用缓存、限流、负载均衡、异步处理及代码优化等策略,以提升性能和稳定性。
|
29天前
|
JSON API 数据格式
携程API接口系列,酒店景点详情请求示例参考
携程API接口系列涵盖了酒店预订、机票预订、旅游度假产品预订、景点门票预订等多个领域,其中酒店和景点详情请求是较为常用的功能。以下提供酒店和景点详情请求的示例参考
|
2月前
|
JavaScript 前端开发 Java
多种语言请求API接口方法
每种语言和库的选择取决于具体需求、项目环境以及个人偏好。了解这些基本方法,开发者就可以根据项目需求选择合适的语言和库来高效地与API交互。
45 1
|
2月前
|
存储 数据可视化 JavaScript
可视化集成API接口请求+变量绑定+源码输出
可视化集成API接口请求+变量绑定+源码输出
62 4
|
2月前
|
API
使用`System.Net.WebClient`类发送HTTP请求来调用阿里云短信API
使用`System.Net.WebClient`类发送HTTP请求来调用阿里云短信API
35 0
|
JavaScript 前端开发
|
Web App开发 .NET 数据库连接