为Android配置允许自签证书认证

最近在用 UniApp 开发一个混合项目,后端部署在内网,用的是自己签的 HTTPS 证书。打包成apk包后,测试了一下请求直接挂掉,报了证书验证不通过的错误:

Trust anchor for certification path not found.

为解决这个问题,我们需要让Android信任我们自己签的 HTTPS 证书

为什么会存在这个问题?

  • Android 从 7.0 开始,默认只信任系统内置的权威证书(比如 Let's Encrypt、DigiCert 这些)。

  • 自己生成的证书,它不认识,直接拒绝连接。

  • 同时,Android 9+ 默认禁止所有 HTTP 明文请求(除非你特别允许)。

经过调研主要有两种办法,一是在Android的系统设置中安装自签证书,但这种办法不太容易实现,毕竟当APP使用面比较广的时候,你是不能给所有用户都装一遍的。第二种就是让apk内部去信任自签证书。

利用Network Security Config解决自签SSL认证

  1. 从服务器中导出证书

  2. 将证书文件放置在Android项目资源文件夹中

  3. 编写Network Security Config文件

  4. 在AndroidManifest.xml中使用Network Security Config文件

# 下载证书 假设IP为192.168.1.100
openssl s_client -connect 192.168.1.100:443 < /dev/null | openssl x509 > my-server.crt
# 移动证书到指定位置
mv my-server.crt /path/to/res/raw/
# 创建Network Security Config文件
cat > /path/to/android/res/xml/network_security_config.xml <<EOF
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <!-- 信任自签证书的内网地址 -->
    <domain-config cleartextTrafficPermitted="false">
        <domain includeSubdomains="false">192.168.1.100</domain>
        <trust-anchors>
            <certificates src="@raw/my-server" />
        </trust-anchors>
    </domain-config>

    <!-- 允许特定域名使用 HTTP(仅当无法使用 HTTPS 时) -->
    <domain-config cleartextTrafficPermitted="true">
      <domain includeSubdomains="true">www.xxx.cn</domain>
    </domain-config>

    <!-- 全局默认:其他所有请求走系统 CA 验证,禁止 HTTP -->
    <base-config cleartextTrafficPermitted="false">
        <trust-anchors>
            <certificates src="system" />
        </trust-anchors>
    </base-config>

    <!-- 调试时允许用户证书(仅 debug 包生效) -->
    <debug-overrides>
        <trust-anchors>
            <certificates src="user" />
        </trust-anchors>
    </debug-overrides>
</network-security-config>
EOF

在AndroidManifest.xml中追加内容:

......
  <application
......
    android:networkSecurityConfig="@xml/network_security_config">
......
  </application>
......

如何自签证书?

在开发、测试或内网环境中,自签证书是一种快速搭建 HTTPS 服务的常用方式。以下是基于 OpenSSL 的自签证书生成完整流程,支持指定域名与 IP 地址,适用于如 Nginx、Apache 等 Web 服务器。

准备一个配置文件 server.conf ,内容如下:

[req]
default_bits = 4096
prompt = no
default_md = sha256
distinguished_name = dn
req_extensions = v3_req

[dn]
CN = 192.168.1.100

[v3_req]
subjectAltName = @alt_names
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment

[alt_names]
DNS.1 = www.xxx.cn
# DNS.2 = xxx.xxx.xxx
IP.1 = 192.168.1.100
# IP.2 = xx.xx.xx.xx

说明:

  • CN:证书的通用名称,通常填写服务器 IP 或主域名。

  • DNS.1DNS.2:允许访问的域名。

  • IP.1IP.2:支持的 IP 地址。

  • keyUsage:定义证书用途,支持签名与加密。

  • subjectAltName:扩展字段,允许证书包含多个域名或 IP。

而后根据是否有现成私钥,选择以下任一命令:

✅ 有私钥(如已生成 privkey.key):

openssl req -new -x509 \
  -key privkey.key \
  -out fullchain.crt \
  -days 365 \
  -config server.conf \
  -extensions v3_req

🔐 无私钥(一键生成私钥 + 证书):

openssl req -x509 -nodes -days 365 \
  -newkey rsa:4096 \
  -keyout privkey.key \
  -out fullchain.crt \
  -config server.conf \
  -extensions v3_req

输出文件说明:

  • privkey.key:私钥文件,务必妥善保管。

  • fullchain.crt:自签名证书文件,可直接用于 Web 服务器配置。

注意事项

  1. 浏览器会警告:自签证书不被信任,浏览器会提示“不安全”。可手动信任证书以消除警告。

  2. 仅限测试/内部使用:不要用于生产环境对外服务,否则可能引发安全风险。

  3. 证书有效期:默认 365 天,可按需修改 -days 参数。

  4. 私钥安全:私钥文件切勿泄露,建议设置权限 600chmod 600 privkey.key


为Android配置允许自签证书认证
https://blog.cikaros.cn/archives/wei-androidpei-zhi-yun-xu-zi-qian-zheng-shu-ren-zheng
作者
Cikaros
发布于
2025年11月27日
许可协议