電信業者 Wi-Fi

電信業者 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 設定檔。

如果是搭載 Android 10 以下版本的裝置,請在電信業者設定管理工具中,為每家電信業者設定 carrier_wifi_string_array 參數,以便新增 Wi-Fi 設定檔。

  • carrier_wifi_string_array:字串陣列,其中每個字串項目都是以半形逗號分隔的 Base64 編碼 Wi-Fi SSID 和 EAP 類型,其中 EAP 類型為整數 (請參閱「可擴充驗證通訊協定 (EAP) 註冊表」)。舉例來說,下列設定適用於使用 EAP-AKASOME_SSID_NAME 和使用 EAP-SIMSome_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-AKA
    • 1:EAP-SIM
    • 6: 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-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'

鍵 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 傳送,以便代管運營商的憑證,其中:

  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-----"
    } ]
    }