返回

Android FIDO2内网Asset Links: 问题与解决

Android

Android FIDO2 私有网络 Asset Links 问题

FIDO2 (Fast Identity Online) 是一种新兴的网络认证协议,允许用户使用生物识别或安全密钥等方式进行身份验证,比传统的密码更加安全可靠。在 Android 平台上集成 FIDO2 时,一项关键的步骤是验证 Web 资产链接,这通常涉及将 assetlinks.json 文件托管在域名的根目录下(例如:https://example.com/.well-known/assetlinks.json)。

在公网环境下,这个过程相对简单,只需要将文件部署到可公开访问的域名即可。但当在内网环境,例如公司内部网络进行测试时,可能会因为设备无法直接访问 assetlinks.json 而遇到问题,导致 FIDO2 验证失败。这个问题的出现,源于 Android 系统的安全策略:它强制要求进行 Web 资产链接验证,并且通常不允许绕过这一机制,而 assetlinks.json 必须通过 HTTPS 可访问的域名。下面,将介绍几种应对内网环境下 assetlinks.json 访问问题的策略。

端口转发与本地域名解析

当服务器运行于私有网络,无法直接从 Android 设备访问时,一种办法是通过端口转发将本地服务映射到 Android 设备可访问的 IP 地址或域名。

  1. 端口转发

    可以使用 adb 命令建立端口转发通道,例如,假设你的本地 HTTP 服务器在端口 8000 上运行:

    adb reverse tcp:8000 tcp:8000
    

    这条命令会将 Android 设备上的 TCP 端口 8000 转发到计算机上的 TCP 端口 8000。 这样,你的应用程序可以通过访问 http://127.0.0.1:8000/.well-known/assetlinks.json(在设备端)来访问文件。

    此方法局限于设备连接到你的计算机时使用,灵活性稍弱,也不适合进行大规模或多设备测试。

  2. 本地 DNS 解析
    另一个解决方案涉及修改你的开发设备上的 hosts 文件,或在网络中配置内部 DNS 解析,将测试用的域名映射到内网服务器的 IP 地址。

    • 在 Android 设备上,hosts 文件位置通常是 /system/etc/hosts (需 Root)。可以使用命令操作:
    ```bash
    adb root
    adb remount
    adb pull /system/etc/hosts
    # Edit the 'hosts' file on computer and push to Android device
    adb push hosts /system/etc/hosts
    ```
    

    在hosts 文件中添加例如192.168.1.10 example.com 这行映射规则后, 将 example.com 映射到内部服务器 IP (192.168.1.10)。 现在,访问 https://example.com/.well-known/assetlinks.json 就直接请求到了内部的服务器,而不需要使用 127.0.0.1:8000。需要注意的是修改设备 hosts 文件通常需要 root 权限。

    • 更佳的方案是在内网 DNS 服务器中设置解析规则,避免每个测试设备都需要手动更改 hosts 文件。

这种方案能很好地模拟真实环境下的域名解析,更加符合测试的实际情况。

本地 HTTPS 服务器和自签名证书

assetlinks.json 需要通过 HTTPS 提供时(通常的推荐方式),就需要一个配置了 HTTPS 的本地服务器。使用 adb 端口转发不能简单地解决该问题,因为你需要配置证书才能实现HTTPS访问, Android 安全策略需要安全连接来执行 Web 资产链接验证。

  1. 生成自签名证书:
    可以使用 openssl 工具生成自签名证书。这虽然无法被外部信任,但是 Android 设备会在开发模式下容忍此类证书:
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -subj '/CN=example.com'

该命令将创建一个自签名证书 cert.pem 和一个私钥 key.pem,有效期 365 天,主题设置为 CN=example.com。注意,请使用你的实际域名替换 “example.com”。

  1. 使用HTTPS服务器 : 使用支持HTTPS的静态服务器(如 Python 的 http.server)并配置上前面创建的证书和密钥。

    python3 -m http.server --https --certificate cert.pem --key key.pem 443
    

确保你本地服务器的文件路径中包含了 .well-known/assetlinks.json。此时使用例如https://example.com/.well-known/assetlinks.json 可以在内网设备中访问此资源。如果通过 127.0.0.1 访问, 需要在 hosts 中添加127.0.0.1 example.com,或使用 DNS 解析,才能直接使用 example.com

这些自签名证书不会被信任的机构签发,浏览器访问时会出现警告,但是在开发和测试阶段是可以被接受的。  也可以设置 Android  信任自签名证书,从而解决验证问题,步骤可查阅相关文档。
  1. Asset Links 文件内容 :确保你的 assetlinks.json 内容正确。其格式如下:

     [{
      "relation": ["delegate_permission/common.handle_all_urls"],
        "target": {
        "namespace": "android_app",
          "package_name": "com.example.your_package",
           "sha256_cert_fingerprints": ["YOUR_SHA256_FINGERPRINT"]
       }
    }]
    

    替换 com.example.your_package 为你的应用包名,YOUR_SHA256_FINGERPRINT 为你的应用的签名 SHA256 指纹。 指纹可使用 keytool 工具获取:

  keytool -printcert -jarfile <你的APK>
上述方案主要侧重于在内网开发测试环境中解决 `assetlinks.json` 的可访问性问题。请务必确保你在生产环境中配置了正确的 `assetlinks.json` 和可信任的 TLS 证书。