Google 致力于为黑人社区推动种族平等。查看具体举措

运营商 WLAN

运营商 WLAN 是 Android 9 及更高版本中提供的一项自动连接功能(使用加密的 IMSI),该功能可让设备自动连接到运营商部署的 WLAN 网络。在网络极为拥挤或手机信号覆盖范围很小的区域,如体育场或地铁站,运营商 WLAN 功能可用于改善用户的连接体验并起到分载流量的作用。

具有运营商 WLAN 功能的设备会自动连接到已配置的运营商 WLAN 网络(具有公钥证书的网络)。当用户手动断开与运营商 WLAN 网络的连接时,该网络将被列入黑名单 24 小时(不会自动连接)。用户可以随时手动连接到已列入黑名单的网络。

在搭载 Android 9 或更高版本且已实现运营商 WLAN 功能的设备上,默认不会通过运营商 WLAN 功能自动连接网络。当设备首次尝试连接到运营商 WLAN 网络时,用户会收到通知。

实现

如需实现运营商 WLAN 功能,设备制造商和运营商必须执行以下操作。

制造商

对于搭载 Android 11 及更高版本的设备,请使用 Wi-Fi suggestion API 为每个运营商添加 WLAN 配置文件。

对于搭载 Android 10 或更低版本的设备,请通过在运营商配置管理器中为每个运营商配置 carrier_wifi_string_array 参数来添加 WLAN 配置文件。

  • carrier_wifi_string_array:一个字符串数组,其中各字符串条目是一个以 Base64 编码的 WLAN SSID 和一个 EAP 类型,二者以英文逗号隔开,并且 EAP 类型是一个整数(请参阅可扩展的身份验证协议 (EAP) 注册表)。例如,以下配置针对使用 EAP-AKA 的 SOME_SSID_NAME 和使用 EAP-SIM 的 Some_Other_SSID:

    config {
      key: "carrier_wifi_string_array"
      text_array {
        item: "U09NRV9TU0lEX05BTUUK,23"
        item: "U29tZV9PdGhlcl9TU0lECg==,18"
      }
    }
    

运营商配置管理器中,为每个运营商配置以下参数:

  • imsi_key_availability_int:标识用于 IMSI 加密的密钥是适用于 WLAN(设置位 1)还是 EPDG(设置位 0),或两者都适用(同时设置位 0 和位 1)。例如,以下配置表示 IMSI 加密适用于 WLAN,但不适用于 EPDG:

    config {
      key: "imsi_key_availability_int"
      int_value: 2
    }
    
  • imsi_key_download_url_string:从中下载 proto 文件(包含用于 IMSI 加密的运营商公钥)的网址。例如,以下配置提供了特定的网址:

    config {
      key: "imsi_key_download_url_string"
      text_value: "https://www.some_company_name.com:5555/some_directory_name/"
    }
    
  • allow_metered_network_for_cert_download_bool:一个标记,表明是否允许通过按流量计费的(移动)网络下载运营商公钥。如果未设置此标记,没有 WLAN 连接的新设备将会因为无法下载密钥而不能连接到运营商 WLAN 网络。

    config {
      key: "allow_metered_network_for_cert_download_bool"
      bool_value: true
    }
    

运营商

如需实现运营商 WLAN 功能,运营商必须启用 IMSI 隐私保护并提供一个公钥。

IMSI 隐私保护

Android 使用公钥加密技术保护用户永久识别码 (IMSI) 的安全。Android 实现了针对适用于 Wi-Fi 的 IMSI 隐私保护的无线宽带联盟 (WBA) 规范。为网络连接启用 IMSI 隐私保护后,用户永久识别码不会通过无线下载的方式以明文传输。

永久识别码加密

经过加密的永久识别码格式如下:

  • 永久识别码采用 <IMSI>@<NAI realm> 格式。NAI Realm 格式为 wlan.mncXXX.mccYYY.3gppnetwork.org,其中 XXX 将替换为 SIM 卡的移动设备网络代码 (MNC),YYY 将替换为移动设备国家/地区代码 (MCC)。
  • 永久识别码使用运营商提供的 RSA 公钥进行加密。该公钥包含在 X.509 证书中。
  • 加密方案为 RSAES-OAEP,并使用 SHA-256 作为加密哈希函数。该加密方案在每次使用时都能确保密文的唯一性,从而避免生成一个可能被追踪的固定识别码。
  • RSA 密钥长度为 2048 位。
  • 加密缓冲区为 256 个字节。
  • 密文使用 Base64 编码。
  • 输出的已加密永久识别码的长度为 344 个字节。
Encrypted Permanent Identity = Base64(RSAES-OAEP-SHA-256(<IMSI>@<NAI Realm>))
密钥标识符

密钥标识符是运营商附加到证书的可选属性值对,可让服务器在身份验证期间找到正确的私钥。密钥标识符的示例:CertificateSerialNumber=123456。如果提供了密钥标识符,则会在身份验证过程中以明文形式发送相应的密钥标识符。

对基于 SIM 卡的 EAP 身份验证方法的修改

如果对某个网络连接启用 IMSI 隐私保护,那么系统在收到 EAP-Request/Identity 时并不会发送永久识别码,而是使用匿名登录进行响应:

SERVER: EAP-Request/Identity
UE: EAP-Response/Identity AT_IDENTITY=<prefix>|anonymous@<NAI Realm>

<prefix> 是可选项。如果 enable_eap_method_prefix_bool 运营商配置设为 true,识别码的第一个字符(anonymous 前面的字符)会在 EAP 交换开始之前将所用的 EAP 方法类型告知服务器。

  • 0 - EAP-AKA
  • 1 - EAP-SIM
  • 6 - EAP-AKA'

如果运营商配置设为 false,该前缀将不会包含在相应消息中。

在响应中,服务器会发送 EAP-Request/AKA-Identity 消息,然后系统会采用以下格式进行响应:

SERVER: EAP-Request/AKA-Identity AT_ANY_ID_REQ
UE: EAP-Response/AKA-Identity AT_IDENTITY=<prefix>|<Encrypted Permanent Identity>|","|"<attribute>=<value>"

识别码的第一个字符会告知服务器使用了经过加密的识别码,或提供配置的 EAP 方法类型:

  • \0 - 经过加密的永久识别码
  • 0 - EAP-AKA
  • 1 - EAP-SIM
  • 6 - EAP-AKA'

密钥标识符属性值对是可选的,如果未使用,则不会附加到已加密永久识别码的末尾。

此时,服务器会从密钥标识符(如已提供)中找到相应私钥,使用运营商私钥解密经过加密的识别码,然后继续完成正常的 EAP 流程。

成功进行身份验证后,服务器会提供可快速重新验证的识别码或临时识别码(非真实识别码),以用于后续连接。如果服务器未提供临时识别码,系统会在后续连接中发送已加密识别码。

运营商证书检索、失效和撤消

如果系统中未安装任何证书,系统会使用 imsi_key_download_url_string 运营商配置中提供的网址下载证书。仅当 allow_metered_network_for_cert_download_bool 运营商配置设为 true 时,系统才会使用移动数据网络。否则,系统只会在有可用的 WLAN 连接时下载证书。

证书失效由系统强制执行。系统会在证书失效日期前 21 天开始尝试对证书进行更新,并使用同一网址下载新证书。

如果证书被撤消,或者服务器无法解密已加密的识别码,服务器将会发送一条包含 AT_NOTIFICATION 代码 General failure (16385) 的 EAP-Request/AKA-Notification 消息以终止 EAP 交换。作为响应,系统会移除相应证书并尝试从同一网址下载新证书。

提供公钥

为托管运营商证书的服务器提供公开网址(推荐使用 HTTPS 协议而非 TLS 协议),其中:

  1. 公钥和失效日期可从证书中提取。
  2. 来自服务器的信息采用 JSON 格式,如下所示:

    Property: key-identifier
    Type: String
    Encoding: UTF-8
    Description: Specifies an identifier that the carrier would like to attach to the certificate.
    Optional: Yes
    
    Property: certificate
    Property alternative name: public-key
    Type: String
    Encoding: Base64
    Description: The content of the carrier's X.509 certificate.
    Optional: No
    
    Property: key-type
    Type: String
    Encoding: UTF-8
    Description: Specifies the module that will use the key. The value for type must be either WLAN or EPDG.
    Optional: Yes. If the key-type property isn't included, then its value defaults to WLAN.
    

    以下是公钥的示例。

    {
    "carrier-keys" : [ {
      "key-identifier" : "CertificateSerialNumber=5xxe06d4",
      "public-key" : "-----BEGIN CERTIFICATE-----\r\nTIIDRTCCAi2gAwIBAgIEVR4G1DANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJVUzELMAkGA1UE\r\nCBMCTkExCzAJBgNVBAcTAk5BMQswCQYDVQQKEwJOQTELMAkGA1UECxMCTkExEDAOBgNVBAMTB1Rl\r\nc3RiT6N1/w==\r\n-----END CERTIFICATE-----"
    } ]
    }