電信業者 Wi-Fi 是 Android 9 以上版本提供的自動連線功能 (使用加密 IMSI),可讓裝置自動連線至電信業者實作的 Wi-Fi 網路。在擁擠或電信涵蓋率極低的地區 (例如體育場或地下火車站),可以使用電信業者 Wi-Fi 改善使用者的連線體驗,並減輕流量負載。
具備電信業者 Wi-Fi 功能的裝置會自動連線至已設定的電信業者 Wi-Fi 網路 (含有公開金鑰憑證的網路)。如果使用者手動中斷與電信業者 Wi-Fi 網路的連線,該網路會列入黑名單 24 小時 (沒有自動連線)。使用者可以隨時手動連線至列入黑名單的網路。
實作
裝置製造商和電信業者必須執行下列操作,才能實作電信業者 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 下載網址。舉例來說,下列設定會提供特定網址:config { key: "imsi_key_download_url_string" text_value: "https://www.some_company_name.com:5555/some_directory_name/some_filename.json" }
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 實作無線寬頻聯盟 (WBA) 規格,以保護 Wi-Fi 的 IMSI 隱私權。針對連線啟用 IMSI 隱私保護服務時,系統不會以無線方式傳輸永久訂閱者身分。
永久身分加密
加密的永久身分格式如下:
- 永久身分的格式為
<EAP-Method><IMSI>@<NAI realm>
。 - EAP-Method 前置字串是單一八位元,用於定義用於驗證的 EAP 方法:
0
:EAP-AKA1
:EAP-SIM6
: EAP-AKA'
- NAI 領域的格式為
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(<EAP-Method><IMSI>@<NAI Realm>))
金鑰 ID
鍵 ID 是運營商附加至憑證的選用屬性值組合,可讓伺服器在驗證期間找出適當的私密金鑰。鍵 ID 的範例為 CertificateSerialNumber=123456
。如果提供金鑰 ID,系統會在驗證程序中以明文傳送。
修改 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-AKA1
:EAP-SIM6
: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-AKA1
:EAP-SIM6
:EAP-AKA'
鍵 ID 屬性值組合為選用項目,如果未使用,就不會附加至加密的永久身分結尾。
此時,伺服器會從金鑰 ID (如有提供) 找出私密金鑰,使用電信業者私密金鑰解密加密身分,然後繼續執行一般 EAP 流程。
驗證成功後,伺服器可以提供快速重新驗證身分或臨時身分 (別名),並在後續連線中使用。如果伺服器未提供臨時身分,則系統會在後續連線中傳送已加密的身分。
電信業者憑證檢索、有效期限與撤銷
如果系統中未安裝任何憑證,系統會使用 imsi_key_download_url_string
電信業者設定中提供的網址,透過 HTTP GET 方法下載憑證。只有在 allow_metered_network_for_cert_download_bool
電信業者設定設為 true
時,系統才會使用行動數據。否則,系統只會在有 Wi-Fi 連線時下載憑證。
系統會強制執行憑證到期機制。系統會在憑證到期日的 21 天前開始嘗試更新憑證,並使用相同的網址下載新憑證。
如果伺服器無法解密加密身分,就會傳送 EAP-Request/AKA-Notification
訊息,並附上 AT_NOTIFICATION
程式碼 General Failure
(16384) 來終止 EAP 交換。
如果憑證遭到撤銷或過期,伺服器會傳送 EAP-Request/AKA-Notification
訊息,其中包含 AT_NOTIFICATION
代碼 Certificate Replacement Required
(16385),以終止 EAP 交換。為回應,系統會套用內部經驗法則,判斷是否應移除憑證並嘗試從相同網址下載新憑證。
提供公開金鑰
請將公開網址提供給伺服器,最好是透過 HTTP over TLS 提供,以便代管運營商的憑證,其中:
- 您可以從憑證中擷取公開金鑰和到期日。
伺服器傳回的資訊為 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-----" } ] }