Android开发-针对明文传输禁止的解决方法

一、Android 9对HTTP明文传输的限制

从Android 9(API级别28)开始,系统默认禁止应用使用未加密的明文HTTP进行网络通信。如果应用尝试进行未加密的HTTP通信,将会受到系统的阻止,表现为各种网络请求错误。例如,使用HttpURLConnectionOkHttp进行HTTP请求时,会抛出类似以下的异常:

java.io.IOException: Cleartext HTTP traffic to <HOST> not permitted

app端报错:

"Network error: CLEARTEXT communication to 192.168.2.138 not permitted by network security policy" 

在这里插入图片描述

原因分析

  • 安全性提升:明文HTTP传输容易被中间人攻击,数据在传输过程中可能被窃取或篡改。因此,Google强制要求应用使用HTTPS来确保数据传输的安全性。
  • 目标API级别影响:如果应用的目标API级别为28或更高,系统默认禁止明文流量。

二、测试开发环境的解决方法

在开发和测试阶段,如果后端服务尚未支持HTTPS,可以通过以下方法允许明文HTTP传输:

方法1:全局允许明文流量

AndroidManifest.xml文件的<application>标签中添加以下属性:

android:usesCleartextTraffic="true"

这将允许应用进行明文HTTP请求。但需要注意,这种方法会降低应用的安全性,仅适用于开发和测试环境。

方法2:配置网络安全策略

res/xml目录下创建network_security_config.xml文件,内容如下:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true" />
</network-security-config>

然后在AndroidManifest.xml文件中的<application>标签中引用该配置文件:

android:networkSecurityConfig="@xml/network_security_config"

这种方法同样允许应用进行明文HTTP请求。

方法3:忽略证书验证

  1. 动态信任自签名证书:在Android应用中,可以通过自定义X509TrustManager来信任自签名证书。
import javax.net.ssl.*;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

// 引入必要的类和接口
// javax.net.ssl 包含用于实现安全套接字层(SSL)功能的类
// java.security.cert.CertificateException 是在证书验证过程中抛出的异常
// java.security.cert.X509Certificate 是 X.509 公钥证书的表示

public class TrustAllCertificates {
    // 定义一个名为 TrustAllCertificates 的公共类

    public static void trustAllCertificates() {
        // 定义一个公共静态方法,该方法不返回任何值,名为 trustAllCertificates
        try {
            // 使用 try-catch 块来捕获和处理可能发生的任何异常

            TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    // 创建一个新的 TrustManager 数组,其中包含一个自定义的 X509TrustManager 实例
                    @Override
                    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                        // 重写 checkClientTrusted 方法,不执行任何操作
                        // 这意味着客户端证书验证将被忽略
                    }

                    @Override
                    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                        // 重写 checkServerTrusted 方法,不执行任何操作
                        // 这意味着服务器证书验证将被忽略
                    }

                    @Override
                    public X509Certificate[] getAcceptedIssuers() {
                        // 重写 getAcceptedIssuers 方法,返回一个空数组
                        // 这意味着没有证书发行者被明确接受
                        return new X509Certificate[]{};
                    }
                }
            };

            SSLContext sc = SSLContext.getInstance("SSL");
            // 获取一个 SSLContext 实例,指定使用 SSL 协议
            sc.init(null, trustAllCerts, new java.security.SecureRandom());
            // 初始化 SSLContext 实例,使用空的密钥管理器数组、自定义的 TrustManager 数组和一个新的 SecureRandom 实例
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
            // 将自定义的 SSLContext 实例的 SocketFactory 设置为 HttpsURLConnection 的默认 SocketFactory
        } catch (Exception e) {
            // 如果在执行过程中发生任何异常,打印堆栈跟踪
            e.printStackTrace();
        }
    }
}

在应用启动时调用TrustAllCertificates.trustAllCertificates()方法。

方法4:自签名证书

通过Flask后端服务器配置自签名证书来解决Android 9对HTTP明文传输的限制是可行的,但这种方法主要适用于开发和测试环境。以下是具体的实现步骤:

1.生成自签名证书
  1. 安装OpenSSL:确保你的系统中安装了OpenSSL。→安装教程

  2. 生成私钥和自签名证书:在终端中运行以下命令:

    openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
    

    这将生成两个文件:cert.pem(证书)和key.pem(私钥)。

2.配置Flask应用使用HTTPS
  1. 修改Flask应用代码:在Flask应用的启动代码中,添加ssl_context参数:

    from flask import Flask
    
    app = Flask(__name__)
    
    @app.route('/')
    def hello():
        return "Hello, World!"
    
    if __name__ == "__main__":
        app.run(host='0.0.0.0', port=5000, ssl_context=('cert.pem', 'key.pem'))
    

    这里,cert.pemkey.pem是上一步生成的证书和私钥文件。

  2. 运行Flask应用:启动Flask应用后,它将通过HTTPS提供服务。

3.安卓客户端配置
  1. 将证书添加到安卓信任库:将生成的cert.pem文件复制到安卓设备上,并将其添加到设备的信任库中。
  2. 配置安卓应用信任自签名证书:在安卓应用中,可以通过配置网络安全策略来信任特定的自签名证书。
4.注意事项
  • 生产环境不推荐使用自签名证书:自签名证书在生产环境中可能会引起安全警告,影响用户体验。在生产环境中,建议使用由受信任的证书颁发机构(CA)签发的证书。
  • 证书有效期:生成的自签名证书有效期为365天,可以根据需要调整-days参数。
  • 证书信任:在开发环境中,确保安卓设备和应用信任自签名证书,否则可能会遇到连接问题。

三、生产环境的解决方法

在生产环境中,强烈建议使用HTTPS来确保数据传输的安全性。如果后端服务已经支持HTTPS,但仍然遇到问题,可以参考以下解决方法:

方法1:确保后端服务正确配置

  • 使用由受信任的证书颁发机构(CA)签发的证书,而不是自签名证书。
  • 确保后端服务正确配置了SSL/TLS,并且没有配置错误。

方法2:动态配置网络安全策略

如果需要为特定域名保留明文流量,可以在network_security_config.xml文件中进行如下配置:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">example.com</domain>
    </domain-config>
</network-security-config>

然后在AndroidManifest.xml文件中引用该配置文件。

注意事项

  • 安全性:在生产环境中,应尽量避免使用明文HTTP传输,以确保用户数据的安全。
  • 应用市场要求:部分应用市场上架要求应用的目标API级别不得低于28,这意味着应用需要适配Android 9的安全策略。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值