【Android】HTTP和HTTPS混合使用

Android P默认https传输协议, 通过SSLSocketFactory手动添加了(数据交互)服务端的证书,但加载的图片资源、html等可能使用的http协议,导致资源无法访问。

先贴一下证书的添加

	private static final String CLIENT_TRUST_PASSWORD = "123456";//信任证书密码
    private static final String CLIENT_AGREEMENT = "SSL";//使用协议
    private static final String CLIENT_TRUST_MANAGER = "X509";
    private static final String CLIENT_TRUST_KEYSTORE = "BKS";
    private static SSLContext sslContext ;

    public static SSLContext getSslSocket(Context context) {
        try {
            //取得SSL的SSLContext实例
            sslContext = SSLContext.getInstance(CLIENT_AGREEMENT);
            //取得TrustManagerFactory的X509密钥管理器实例
            TrustManagerFactory trustManager = TrustManagerFactory.getInstance(CLIENT_TRUST_MANAGER);
            //取得BKS密库实例
            KeyStore tks = KeyStore.getInstance(CLIENT_TRUST_KEYSTORE);
            InputStream is = context.getResources().openRawResource(R.raw.xxx);
            try {
                tks.load(is, CLIENT_TRUST_PASSWORD.toCharArray());
            } finally {
                is.close();
            }
            //初始化密钥管理器
            trustManager.init(tks);
            //初始化SSLContext
            sslContext.init(null, trustManager.getTrustManagers(), null);
        } catch (Exception e) {
            Log.e("SslContextFactory", e.getMessage());
        }
        return sslContext;
    }

再在okhttp中引用

	SSLSocketFactory sslSocketFactory = Https.getSslSocket(context).getSocketFactory();
	
	OkHttpClient.Builder builder = new OkHttpClient()
	                .newBuilder()
	                .sslSocketFactory(sslSocketFactory)
	                .connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)
	                .readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
	                .writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS);
  • 问题1:sslSocketFactory(sslSocketFactory)AS提示该方法已过时;
  • 问题2:系统默认通讯为https,该方法只有在发起okhttp请求时才可用。

过时不过时的,能用就先不管了,后续再找替代方法。主要的问题在于问题2,当在请求其他资源时,如果不是https协议,就无法请求。关键点在于:

android:usesCleartextTraffic=“true”

即是否使用明文通讯

方案:动态设置android:usesCleartextTraffic的值

百度了一下,各种骚套路 Java一切皆可反射!
不过大部分例子都是动态更改包名、icon等,以及通过gradle区分debug与上线版本等。本人能力有限,这些例子都不大适用。

拿着webview上的错误,Google一波。
Android 8: Cleartext HTTP traffic not permitted
这里边的都是只信任自己的域名,也就是添加白名单。例如:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">***Your URL(ex: 127.0.0.1)***</domain>
    </domain-config>
</network-security-config>

但我需要的是反其道而行之,直接来个反相?

	<?xml version="1.0" encoding="utf-8"?>
	<network-security-config>
	    <domain-config cleartextTrafficPermitted="false">
	        <domain includeSubdomains="true">***Your URL(ex: 127.0.0.1)***</domain>
	    </domain-config>
	</network-security-config>


	<application

		android:networkSecurityConfig="@xml/network_security_config"
        android:usesCleartextTraffic="true">

设置全局明文传输,只有在指定域名下才适用https。
结果很显然不行,设置方式不对。

再搜一下:How to allow all Network connection types HTTP and HTTPS in Android (9) Pie?
这一页的回答虽然不多,但看到了新的东西:base-config

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true">
        <trust-anchors>
            <certificates src="system" />
        </trust-anchors>
    </base-config>
</network-security-config>

也就是说,里边至少有两个标签:domain-configbase-config
查到了关键点,看看国内这方面的文章,一搜,果然有,算是一篇科普向的文章:Android网络安全配置
列出两个关键点:

  • base-config,默认的配置,不在 domain-config 范围内的所有连接所使用的配置。

<trust-anchors> 证书集合,可包裹多个 证书

  • domain-config。满足domain规则所使用的配置,可配置任意多个,domain-config的嵌套表示继承外层的配置规则。

<trust-anchors> 证书集合
<pin-set> 固定的证书,通过 expiration 配置过期时间,可包裹多个 证书
<domain> 域名规则,通过 includeSubdomains 配置是否支持子域名
<domain-config> 嵌套规则

依葫芦画瓢:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="false">
        <domain includeSubdomains="true">地址</domain>
    </domain-config>
    <base-config cleartextTrafficPermitted="true"/>
</network-security-config>

大概意思是:默认使用明文,但在与地址通讯时,使用https协议加密传输。
运行一下,使用Fiddler抓抓包,结果如下:
Fiddler抓包
数据交互是https协议,同时可以加载http的资源。
好,完结。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值