運營商 Wi-Fi 是 Android 9 及更高版本中提供的自動連接功能(使用加密的 IMSI),它允許設備自動連接到運營商實施的 Wi-Fi 網絡。在體育場或地鐵站等擁堵嚴重或小區覆蓋範圍最小的區域,運營商 Wi-Fi 可用於改善用戶的連接體驗並減輕流量。
具有運營商 Wi-Fi 功能的設備會自動連接到配置的運營商 Wi-Fi 網絡(具有公鑰證書的網絡)。當用戶手動斷開與運營商 Wi-Fi 網絡的連接時,該網絡會被列入黑名單 24 小時(不會自動連接)。用戶可以隨時手動連接到黑名單網絡。
在運行 Android 9 或更高版本並實施了運營商 Wi-Fi 的設備上,通過運營商 Wi-Fi 自動連接默認處於關閉狀態。當設備首次嘗試連接到運營商 Wi-Fi 網絡時,會向用戶發送通知。
執行
設備製造商和運營商必須執行以下操作才能實施運營商 Wi-Fi。
製造商
對於運行 Android 11 及更高版本的設備,請使用Wi-Fi 建議 API為每個運營商添加 Wi-Fi 配置文件。
對於運行 10 或更低版本的設備,通過在運營商配置管理器中為每個運營商配置carrier_wifi_string_array
參數來添加 Wi-Fi 配置文件。
carrier_wifi_string_array
:一個字符串數組,其中每個字符串條目是 Base64 編碼的 Wi-Fi 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
:從中下載包含用於 IMSI 加密的運營商公鑰的 proto 的 URL。例如,以下配置提供了一個特定的 URL: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
:指示是否允許通過計量(蜂窩)網絡下載運營商的公鑰的標誌。如果未設置此標誌,則沒有 Wi-Fi 連接的新設備將無法連接到運營商 Wi-Fi 網絡,因為它不允許下載密鑰。config { key: "allow_metered_network_for_cert_download_bool" bool_value: true }
運營商
要實現運營商 Wi-Fi,運營商必須啟用 IMSI 隱私保護並提供公鑰。
IMSI隱私保護
Android 使用公鑰加密保護訂閱者永久身份 (IMSI) 的機密性。 Android為 Wi-Fi 的 IMSI 隱私保護實施了無線寬帶聯盟 (WBA) 規範。當為連接啟用 IMSI 隱私保護時,永久訂戶身份不會在空中以明文方式傳輸。
永久身份加密
加密永久身份的格式如下:
- 永久身份的格式為
<EAP-Method><IMSI>@<NAI realm>
。 - EAP-Method 前綴是一個單字節,用於定義用於身份驗證的 EAP 方法:
-
0
:EAP-AKA -
1
:EAP-SIM -
6
:EAP-AKA'
-
- NAI 領域格式為
wlan.mnc XXX .mcc YYY .3gppnetwork.org
,其中XXX
替換為 SIM 卡的移動網絡代碼 (MNC),YYY
替換為移動國家代碼 (MCC)。 - 永久身份使用運營商提供的 RSA 公鑰加密。公鑰包含在X.509證書中。
- 加密方案是使用 SHA-256 作為加密散列函數的RSAES-OAEP 。這種加密方案保證每次使用該方案時都有一個唯一的密文,從而避免了另一個可跟踪的持久身份。
- RSA 密鑰長度為 2048 位。
- 加密緩衝區為 256 字節。
- 密文使用Base64編碼。
- 輸出的加密永久身份長度為 344 字節。
Encrypted Permanent Identity = Base64(RSAES-OAEP-SHA-256(<EAP-Method><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
運營商配置中提供的URL,通過HTTP GET方式下載證書。僅當allow_metered_network_for_cert_download_bool
運營商配置設置為true
時,系統才使用蜂窩數據。否則,系統僅在 Wi-Fi 連接可用時才下載證書。
證書過期由系統強制執行。系統在證書到期日期前 21 天開始嘗試更新證書,並使用相同的 URL 下載新證書。
在服務器無法解密加密身份的情況下,服務器會發送帶有AT_NOTIFICATION
代碼General Failure
(16384) 的EAP-Request/AKA-Notification
消息以終止 EAP 交換。
在證書被撤銷或過期的情況下,服務器會發送一條EAP-Request/AKA-Notification
消息,其中包含AT_NOTIFICATION
代碼Certificate Replacement Required
(16385) 以終止 EAP 交換。作為響應,系統應用內部啟發式方法來確定是否刪除證書並嘗試從同一 URL 下載新證書。
提供公鑰
向服務器提供公共 URL,最好使用基於 TLS 的 HTTP,該服務器託管運營商的證書,其中:
- 可以從證書中提取公鑰和到期時間。
來自服務器的信息採用 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-----" } ] }