# 「安心出行」能否安心使用? 作者:Headuck 香港政府新推出的「安心出行」App,由 react native 寫成,因此Android App 內主要的運作是在 Javascript 中進行,Java 的部份主要為 react native 本身及所使用 library 的 “native” module ,如背景下載,相機操作,網路等介面。 Android 版本似乎再細分為 Google Play 及華為版本,以下所述的是根據從第三方下載的 Google Play 版本。  # 結構 如上文所述,程式主體以 Javascript 編成,已經過 uglify 成為一個大 Javascript 檔,放於 asset/index.android.bundle 內。該 bundle 有超過 1200 行,當中 module 名稱及大部份 function 及 variable 名已被縮為一個字元,每行大概對應一個 Javascript Module。 要查看內容,要先用 js-beautify 回復為較正常的縮排格式,大約有 110k 行。 # 未能搜尋 「安心出行」在 Google Play 的評語,最多的問題竟然是(上架頭一日)未能搜尋到此 App,要知索引更新其實是 Google Play 的問題,不料帶來政府故作神秘的指責。 # GET_TASKS 權限問題 較引起關注的是 android.permission.GET_TASKS,在 Google Play 的描述為 retrieve running apps,在 Android 5 以前是可以藉 getRecentTasks 及 getRunningTasks ,偵察其他 App 的執行情況,亦即可監視用戶活動,但其後(API 21) Google 已大幅限制非系統 App 可看其他 App 的資訊,非系統 App 僅可以偵察自已 App 其他 Component 的情況。 因此除非你使用 Android 5 以前的系統,否則基本上此權限沒有監視其他活動的能力。(利申,「小鴨幹線」(最低要求仍為 Android 2.2)有要求 GET_TASKS 權限,在舊機種偵察電話進程是否在前景、「小熊來電」亦有同一權限)。 那麼「安心出行」(最低要求 Android 4.1) 使用 GET_TASKS 權限做什麼呢,原來是由於這個 react native App 用了 react-native-background-fetch 這個 react native 函式庫(library)來在背景下載資料,而 GET_TASKS 權限是這個 library 的要求(在編繹時所有 library 的權限要求會合併,變為 App 的權限)。使用權限的原因,是在背景下載時偵測本身的前景 App 是否在執行,若是的話,可以與前景 App 溝通。見 BackgroundFetch.java 第271行。 在「安心出行」中似乎此處為唯一可能使用此權限的地方,因此,即使 Android 5 以下,亦未有證據構成問題。 事實上,去年已有該 library 用戶建議,移除 library 對 GET_TASKS 權限的依靠,改以其他方式偵測前景 App ,以免引起私隱誤會,見此 Github issue,不過作者對建議似乎有保留。 不過,open source 的其中一項好處,是源始碼可以自行修訂的。政府若要回應關注,將該 library fork 出來再作稍微修改,便可在更新「安心出行」時移除該權限,符合最低權限的聲稱。事實上,同一程序不同模組間的溝通有大量替代方案,如 broadcast 機制、event bus、RxJava 等。 # 有否收集過量資料? 回到 Javascript 部份,似乎除了 Google Firebase 傳送,網路只定義了以下接口: ## 下載: CONFIG: 下載組態檔,該檔定義某些參數,如不同種類的接觸(目前為預設及的士)的資料保留日期(目前為 31 日),配對定義(14日內),check out 提示時間(1小時),以及下載新版的通知。 GET_BATCH_FILES: 下載感染個案的資料檔目錄 (JSON) DOWNLOAD_KEYS: 下載感染個案的詳細到訪資料(ZIP Protobuf 格式) 取得其他供顯示的 WEB 內容,如網頁,私隱政策等。 ## 上傳: OCR:上載的士車牌圖檔供 OCR 文字辨識,只上載圖像檔 VERIFY_PIN: 供確診者上載由政府提供的一次性密碼,加上隨機 UUID 以作確認,供之後上載電話內的詳細到訪資料 UPLOAD_KEYS: VERIFY_PIN 確認後實際上載確診者到訪資料,由於有密碼確認,可防止有人惡意上載假資料。 似乎在確診者以外,並未發現有特別的收集資料情況,如各類手機辨識碼等,(不過注意若有意隱藏,只靠正常看部份程式碼難以排除任何可能性)。 不過要注意,OCR 文字辨識部份,所攝的圖像是會上傳到政府伺服器以作辨認,代碼類似下面說明:  雖然沒有特別傳送任何額外資料,但流動網絡 IP,手機 agent string (包括機型等)仍會連同車牌資料上傳(伺服器會提供辨認後的車牌),一般亦會紀錄在 log 內。 事實上大部份手機有足夠能力,在離線時自行進行 OCR 運算(尤其這裏只涉及統一格式的英數字),若可以離線 OCR ,可較全面地免除顧慮,更符合資料保存於手機內,不會上傳中央資料庫的說法。 # 程式紀錄了什麼資料 ## Check in 在用戶以程式掃描 QR Code 後,程式會讀取及驗証 QR Code 內容,以記錄用戶到訪地點。與的士車牌的做法不同,為減少上網核實或讀取地點資料引起私隱問題, QR Code 的設計是在 QR Code 內包含所有要紀錄的地點資料,以及核實用的 hash 編碼。 例如報載「良田體育館」的 QR Code,用普通掃描程式即可讀到以下編碼: HKEN:0gxr8l5A6eyJtZXRhZGF0YSI6bnVsbCwibmFtZVpoIjoi6Imv55Sw6auU6IKy6aSoIiwibmFtZUVuIjoiTGV1bmcgVGluIFNwb3J0cyBDZW50cmUiLCJ0eXBlIjoiU1BPUlRTQ1VMVFVSQUxSRUNSRUFUSU9OQUwiLCJoYXNoIjoiZTczODE4YjFjN2U4MDUzM2E4MjI3NjE5NzZhMmMwNTJmMWUwNTQzZTQ2ODM0MDk1ODZmZDg5OTRhM2MxZmU3NiJ9 當中開始的 HKEN: 為「安心出行」編碼固定的前綴,接下來的一位 0 標示此為場地編碼,再之後的 8 位 gxr8l5A6 是地方 ID,之後剩下的(eyJtZ....3NiJ9)全部是經 base64 encode 的 JSON 地方資料,經任何 base64 decoder 即可還原為  解碼後程式會核對 hash code (checkHash),方法是將上述前綴 HKEN,加上地方 ID 及四位的後綴(可在程式內找到,不在此公開),併合為一字串再做一次 SHA256 hash 編碼,將結果以 16 進數列出,便應與 JSON 內的 hash 刎合。 這裏指出一點,由於要離線驗證, hash 方法完全存在於程式中,可輕易找到產生 hash 的方法,沒有保安可言。但 QR Code 卻將整個 hash code 編碼納入,佔去三份之一的長度,令 QR Code 不必要地長。其實只核對頭幾個 byte,如 e73818b1 在實際上是毫無分別的。 在核對後,程式會將有關資料,連同目前時間 (13 位 millisecond Unix timestamp) 作為 Check In 時間,暫時以非加密方式儲存到手機檔案系統 (saveVenueVisit),當中是使用 React 的 AsyncStorage 。  如果是 Check in 的士的話 (saveTaxiRecord),資料為  ## Check out 用戶離開 Check In 地點,會使用 Check Out 功能,程式從檔案系統取出之前 Check In 資料(及從 AsyncStorage 刪除該份非加密資料),紀錄 Check out 時間(或用戶輸入時間),成為以下資料:  之後程式會將紀錄進行「加密」及儲存。 # 所謂加密 程式的「加密」方法 (generateCheckInRecord),是先將以下資料併為一字串(暫稱 dataString): 隨機 8 位字串 8 位 venueId 8 位 groupId (若沒有,用 00000000 (NO_GROUP) 代替) 13 位 inTs (轉為字串) 13 位 outTs meta (長度不限),即包括上述 venueName 內的地方資料 再用以下方法產生 16-byte Key (128 bit): 將 inTs 除以 60000 成為分鐘單位,僅保留整數部份 (keyInterval) 將 keyInterval 轉為字串,使用 HKDF (HMAC-based Extract-and-Expand Key Derivation Function)(見 futoin-hkdf 程式庫)產生 Key,當中指定使用 SHA-256 為 HMAC function,及特定的 info 参數(可在程式內找到),沒有使用 salt 参數。  然後利用 CryptoJS.AES 以 key 加密資料字串(當中 Initialization vector (IV) 可在程式內找到),再轉為 base64 encoding。  之後,將 keyInterval 及加密的 keyData ,連同 upload flag (false,表示未上載) ,作為出行記錄數據,一併存到資料庫中的 LocationHistory table。 以上就是政府不斷強調的加密儲存,例如創科局局長最近(11 月 18 日)在特區人大立法會會議指出, 感染風險通知流動應用程式「安心出行」已通過獨立第三方的保安風險評估及審計和個人私隱影響評估,確保符合《個人資料(私隱)條例》規定。…. 程式採用 AES-256 加密標準保護儲存在用戶手機內的出行記錄數據。[1] 先不論局方將用 128-bit key 的 AES 加密說成 AES-256(因為這不是重點),因為只要知悉有關方法(簡單分析 JavaScript 碼使可得出),任何人若取得 LocationHistory table 中的資料,即可從紀錄中的 keyInterval 欄位,輕易透過標準的 HKDF ,取得之前加密用的 128-bit AES key ,再輕鬆用 AES-128 還原 keyData (AES 是所謂對稱密鑰演算法,加密及解密是用同一條 key)。這類保安方式,頂多稱為 security by obscurity。向公眾聲稱資料受 AES-256 加密保護,即使不是 128-bit 充 256-bit,也是極具誤導性。這類似將門鎖鎖匙藏在門前地氈底,門鎖有多堅固,也是徒然。[2] # 加密虛招何來? 公平地說,在「安心出行」的各種限制下(不上傳資料,在用戶端背景配對確診資料,為普及及方便使用而不利用一些手機的硬件保安功能,如生物辨識,或要求每次 Check in 或配對前輸入密碼),在用戶手機內的資訊,根本難以作有效加密,因為所有解密所需的資料都在程式當中(當然從陰謀論者角度,在此機制下,政府本身亦可輕易解密)。若手機失竊,有關資料只能和很多其他私隱資料一樣,靠手機本身的保安設定保護。同樣道理,QR Code 的 hash 編碼,不論用幾多 bit ,在這情況下亦難以保證 QR Code 的真確性。 不過,政府制訂招標要求時,往往無視上述限制,既要方便又要保安,寫入了無意義的加密要求。開發商也許明知沒有用,也要照花資源應付這種表面性的要求,只需提高標價,袋袋平安,。而這種門鎖藏在地氈底的保安虛招,竟又可通過政府創科局,以至花公帑外聘的「獨立第三方的保安風險評估及審計」,成果亦可供局長吹噓,各取所需,皆大歡喜。 反正 False Security is Worse than No Security 這類老生常談,在講求 PR 的環境下是不太適用的。 # 下載組態及資料更新 ## 下載設定及權限 如前面所提及,程式使用了 react-native-background-fetch 做背景下載。值得一提的是,其下載設定為  NETWORK_TYPE_ANY 是指,程式不論是 WiFi 或是流動網絡,只要有連線,均會下載資料作更新。與此相關的是,手動上載的士車牌影像供 OCR 前,亦沒有特別檢查 WiFi 狀態(因為並不預期在的士內可以穩定利用 WiFi [1])。 因此,資科辦解釋「安心出行」權限時 [2] 所指「流動應用程式需要網絡存取、Wi-Fi連線(以節省用戶數據使用)、媒體及檔案相關權限,以保障用戶私隱」,「應用程式需要在背景執行,並使用手機的上網功能,將有關資料定時下載… 。因此,流動應用程式需要網絡存取、Wi-Fi連線、容許程式可以在背景執行及發出通知的相關權限」,具有誤導性: 程式根本沒有特別設定,限制只使用 WiFi 上下載,以節省流動數據, 上述「Wi-Fi連線相關權限 」在前文後理下,可理解為程式要求的 ACCESS_WIFI_STATE(查看Wi-Fi連線)權限及 CHANGE_WIFI_MULTICAST_STATE(允許接收Wi-Fi多點傳播封包)。事實是,若單純使用 WiFi 連線,INTERNET 網絡存取權限已足夠。查看 WiFi 連線權限,是用於取得 WiFi 連接有關的額外資訊,在 Android 6 之前更可取得附近 WiFi 網絡(Access Point)識別資料從而推斷用戶位置。從程式功能看,似乎沒有此權限的必要。[3] 觀乎實際程式碼,似乎是開發商使用了一些涵蓋廣泛功能的程式庫,因而附帶要求了相關 WiFi 權限,與當局所指需要 WiFi 連線或節省用戶數據無關。 # 組態檔 在下載時,如第一部份所述,程式會先下載一個載有目標檔案資料的目錄,附更新時間(updatedAt),以讓程式自行決定要下載什麼資料(getBatchFile),內容例子:  程式接着再下載組態檔(getConfig)。組態檔的內容如下:  程式內的用戶紀錄及下載感染者紀錄都是按 type 分開處理,上述組態檔中,type = DEFAULT 是指預設不同類型場所紀錄的處理,而 type = TAXI 是指的士車牌的紀錄。 overlapDuration:60000 (一分鐘),與感染者在同一場所超過一分鐘,會視為直接接觸。 groupOnly:未啟用,若啟用時會收窄接觸的定義,除處於同一場所外,要與感染者紀錄的 group ID 相同,才視為有接觸(目前 group ID 全部設為 NO_GROUP,即 “00000000”)。 indirectWithin:86400000 (一日,僅用於的士)及 indirectDuration:1000(一秒,僅用於的士),若用戶和感染者使用同一的士,即使沒有直接接觸,只須在感染者離開的士後的 24 小時內進入的士,逗留超過一秒,便視為間接接觸。 matchingKeyDays:14(兩星期)程式下載資料後,只會核對自該日零時對上兩星期起至今的紀錄。 dataRetentionDays:31(31日)下載資料後會觸發清除用戶超過31 日的到訪的紀錄。(程式統一使用 type = DEFAULT 的設定) checkOutReminderMs:3600000(一小時)Check in 後一小時會提示用戶 Check out。 forceUpdateVersion: “0.0.0”,若有新版本,或會強制用戶更新,暫時(11月底)未啟用。 enableCI / enableFollowUp:未啟用,程式內沒有相應編碼。 注意這個組態檔是不會儲存的,每次使用時會重新下載,即是說內容隨時可由當局改變,包括當局掛在口邊,31 日清除到訪的紀錄的設定。此外,forceUpdateVersion 若啟用,用戶要使用程式或須下載新版本,即使現行版本經檢視未有發現問題,新版本仍是沒有保證。特別是 group 配對 / enableFollowUp / enableCI [4] 等功能,目前未有資料,但觀乎名稱,可能日後會如當局所指的「按部就班」,逐步加強追蹤及跟進的功能。 # 感染者到訪資料檔 根據前述 getBatchFile 所載的目錄資料,程式會下載自安裝或上次更新後,所更新的感染者到訪資料(downloadKeys)。資料是經 base64 編碼及 zip 壓縮的 Protobuf 檔案格式 [5]。 資料解壓及合併後,成為按 type(如 TAXI)分類的感染者到訪資料列表,內容主要是如第二部份所述,經「加密」的 keyData(地點及時間資料)及可用於解密的 keyInterval。 而實際下載的有關資料內容,就是政府公布的確診者到訪大廈資料,以下為例子:  注意可能由於資料不是來自程式,出入時間基本涵蓋全日,即只提供日期資料。 程式接下來﹐便是將下載資料按組態檔中的設定核對,以找出是否有與感染者「直接接觸」或「間接接觸」的個案(同一時段及地點同時有「直接接觸」及「間接接觸」,會視為直接接觸,不過在下載資料涵蓋全日看來,這個已沒有太大意義)。有關個案及配對資料會存到 Inbox 內,資料如下: date: 目前時間 title: 訊息主題,“Possible COVID-19 Notification” template: 訊息,分為的士及其他一般場所兩種 exposedDate: 用戶 Check In 場所時間 checkOutTs: 用戶 Check Out 場所時間 metaData: 即上文所指的venue資料,如地方種類,名稱及的士車牌,以 JSON 存放 diff: 直接接觸:與感染者同處一場所合計時間,間接接觸:用戶處於場所(如使用的士)合計時間 uuid: 即時產生的隨機 UUID confirmedKeyData: 下載感染者配對的 keyData contactType: 間接接觸為 “I”,直接接觸為 “D” isRead: 是否已讀 若有發現新的接觸個案,會向用戶發通知,更新首頁的通知總數資料。 順帶一提,下載資料 zip 檔案及解壓檔案會即時清除,核對後只會存放成功核對的相關資料到 Inbox。當中由於沒有存放感染者的 keyInterval,在 Inbox 中的感染者配對的 keyData 只能用來當 hash 用,以確保不會重覆通知,但不能還原資料。 另一方面,程式內雖有清空 Inbox 功能的編碼(deleteInbox),但似乎沒有使用,讀取後只會劃為已讀。一旦 Inbox 有接觸感染者的訊息,可能除了清除 App 所有資料或重裝外沒有方法消除。 問題是,Inbox 訊息總數是當眼地顯示在程式首頁,如無法清空,而政府場地/私人物業要強制訪客打開此程式,公開地在物業管理員監視下掃描 QR Code,變相是要公開出示這個可以解讀為個人的「感染風險指數」的數字(事實上,程式內稱此數字為 “Exposure Count”)。 可以想像一下,當人人要使用程式,很快便得悉這個數字的「功能」,當「風險高企」者被發現,除了附近人士彈開,同時亦難以排除在監視的物業管理員可能被要求對「風險高企」者有特別對待,如進一步檢查接觸紀錄,否則禁止進入。 # 這不已經是「健康碼」了嗎?  廣告:不用搶購 3310,Android 2.2 – 4.0.4 不兼容「安心出行」 但可安裝「小鴨幹線」攔截電話 # 清除舊紀錄 當下載,核對及發出通知完成後,在檢查上次清除紀錄日期不是今天後(每天最多清除一次),程式會清除今天零時對上 31 日(視乎組態檔的 dataRetentionDays )於 LocationHistory 中的用戶到訪紀錄(clearDataOverRetentionDays)。由於紀錄作了「加密」,程式要讀取 LocationHistory 所有紀錄,逐一解密及抽取 Check In 時間作比較,才能決定要清除的紀錄。 此外,如上面指出,Inbox 的與感染者接觸資料沒有清除,這技術上已違反了政府「出行記錄亦會在存放手機達31天後自動刪除」的說法,因為 Inbox 也包含了用戶到訪地點及時間詳情。 # 使用 Hermes 虛擬機 前面寫到對 Android 1.0.4 版本的分析方法,在半個月後更新的 1.0.5 版本已經失效。「安心出行」改為用 React Native 的 Hermes 虛擬機去執行以 JavaScript 編寫的程序,當中JavaScript源碼會先編繹為類似 bytecode 的二進位檔案才放到 APK 檔中。因此 APK 檔內再找不到 JavaScript 的編碼。 使用 Hermes 虛擬機的當然有其好處,如加快速度及減少內存消耗,不過同時增加了分析編碼的難度,在經 hbcdump 程式將 index.android.bundle 二進位檔反組繹後,得出類似的程式:  和 Java 或 smali bytecode 不同,由於 Hermes 仍是新技術,目前似乎未有公開的反編繹程式將之還原為較可讀的 JavaScript 格式,但多花時間熟習後還是可找到程式邏輯的。不過,在沒有工貝協助下,一些搜尋方式便變得困難,變相隱藏功能亦較容易,例如現時未能確保是否已找出「安心出行」與政府伺服器(「大台」?)間的所有API。 雖然使用 React Native 的 Hermes 技術(目前仍是 opt-in)絕對有合理理由,但時間上,卻恰在 JavaScript 碼被分析(包括加密虛招問題及 AES 加密 bit 數貨不對辦)後,而不是首次公開的 1.0.4 版前完成這些基本設定,難免令人對其動機是否純為改善效率產生聯想。 # 加強 AES 加密 在 12 月初的 1.1.0 版,「安心出行」加入了檢視到訪紀錄的功能,因此實際上,「資料加密儲存於手機」這種做法,已經毫無實質意義,因為「安心出行」App 檢視功能本身已自動解密,有關資料只受身機本身的保安機制保護。 奇怪的是,開發商竟還大費周章,將 AES 加密 bit 數由 128 增加到 256,這包括額外編碼,將用戶原有的資料用逐項以 128 bit 解密,再以 256 bit 加密,在資料庫增加欄位 isNew,分辨紀錄是否已進行升級等,而伺服器的 API 亦作出相應升級。 究竟是開發商未達(無謂的)加密要求,被發現後而補鑊,還是局長在立法會說 256 bit 加密時用了 Doraemon 的口講成真揚聲器,便不得而知了。 用之前門鎖的譬喻,就是當局或開發商一方面要把鎖匙長期插在門鎖方便開門,另一方面又花資源將門鎖加固。 當然,和「強烈建議」要打咭出入政府總部的公務員用「安心出行」一樣,一件沒有實質意義的事,不代表沒有其宣傳價值的。譬如張建宗司長最近(2月14日)在facebook的帖文,便繼續沿用資料「加密存放於用戶自己的手機」的舊口徑,來為「安心出行」宣傳。 # 「安心出行」API URL [19/2 更新: 此段適用於 1.1.4或之前數個版本,1.1.6版已加回直接連結] 原本程式連接至「大台」的 API URL base,是 hard code 在程式內的,不過在新版中,該 URL 已不再直接寫在程式內,而是從 https://www.leavehomesafe.gov.hk/site.json 取得。該網址目前返回以下 JSON  (從 App 上傳資料用 api ,下載用 json)因此,如果用 Ad blocker (如 F-Droid 版的開源 Ad-blocker Blokada – 注意 Google Play 版因名顯原因,功能不全),在廣告阻加擋〉已封鎖主機中,加入 www.leavehomesafe.gov.hk 到阻擋名單,便會阻止「安心出行」取得 API 位置,繼而停止「安心出行」與「大台」溝通,因此亦可停止浪費數據的強制更新。如在網站如 apkpure 下載舊版的「安心出行」,若使用時沒有使用阻擋名單,程式會發出更新通知。若對安心出行有疑慮,這可能是其中一種利使用方法。 利申/宣傳:小鴨全力支持抗疫,特此呼籲,使用「安心出行」,若長時間阻擋,會錯過感染風險通知,若作出此設定,請在合法情況下安裝及使用如「出 duck 嚟行」的到訪紀錄程式,以便收到通知。「出 duck 嚟行」下一版將直接連接 API 網址,以下載資料並發出感染風險通知,單是阻擋 www.leavehomesafe.gov.hk 不影響運作,唯無法估計政府會否不斷更改 API 位置或以其他行動禁制使用。 # 能否安心? 回應主題,雖然前文在 1.0.4 版的 App 未見有可疑之處,(之後的版本因透明度降低未能評論),但據政府公布及其他跡象,政府會按部就班,加入更多涉及私隱的功能及要求更多權限。 # 自願實名登記 首先,根據傳媒報道流出的 1.0.0 版截圖[6],顯示安心出行原本是有紀錄「實名」的機制的。在設定版面,有「聯絡資料二維碼」一項,按入後再輸入姓名及資料,便會將資料生成二維碼,按截圖所載,應是供場地負責人掃描,而用戶須先同意場地負責人,將資料提供給政府,才會產生此二維碼。  截圖顯示的日子為10月27日,距離「安心出行」推出僅十多日。因此,推斷「安心出行」計劃可能已準備好另一套程式(「安心出行」場地負責人版),專供場地負責人掃描此收集「聯絡資料二維碼」,以作紀錄及上傳給政府。 但短短十多日後出街的 1.0.4 版,此功能離奇消失。報道中介紹上述功能的,是副政府資訊科技總監黃志光。可以推斷,有更高層的官員,以非技術原因,在最後關頭抽起此項功能。那麼究竟是什麼原因導致抽起此項功能呢,會否是為讓公眾起初較易接受程式?若程式多人接受,會否加回此功能,並強制不同場所執行呢?(尤其是政府有日「發現」,市民在食肆或其他場所留低的姓名及聯絡資料,含糊不清 …)恐怕政府有關官員以外,沒有人知道。 # 個案跟進及調查 在上文第三部,「安心出行」下載的組態檔中,有 enableCI 及 enableFollowUp 的字眼,兩者皆設定為 False,即是尚未啟用。CI 有估計是 Case Investigation 的意思。問題是如果「安心出行」維持匿名及免登記,又不會上傳記錄,程式可以如何作跟進及個案調查呢? 可以想像,若要進行跟進及調查,程式日後可加入(或原本已存在,只是暫時抽起,日後補回)相關功能,例如政府以類似目前的強制性措施,令公眾「自願」實名登記及同意上載資料,日後若透過「安心出行」發現確診者的直接或間接接觸者,相關資料便可自動上載,以讓當局直接「跟進」接觸者有否受感染(例如強制檢測),甚至在不明源頭的情況,進一步將這些接觸者的到訪紀錄上傳(若多人使用「安心出行」,這些資料可以合併為接觸史的 social graph),一層一層的進行深入的「個案調查」,找出相關源頭。 上述當然只是憑兩個參數名稱天馬行空,但純以防疫角度,政府若掌握這些資料無疑是有幫助的,政府是否有類似類似後着,在「安心出行」使用普及時推出,希望公眾自願「為抗疫而而放下私隱考慮」(引局長的說法),目前仍是未知數。 # 藍芽定位 政府正與香港大學研究 beacon 藍芽定位,在小巴加設 beacon,讓「安心出行」自動用 BLE 即 Bluetooth Low Energy 記錄行蹤,而且已經進入試驗階段。 首先,這意味程式將加入令部份人更不安心的權限,包括藍芽相關權限,以及 Fine Location 權限(即和 GPS 相同的權限:使用 Bluetooth scan 自 Android 6 起要求 Coarse Location 權限,Android 10 起要求 Fine Location 權限,為在近年的機款運作,程式須要求後者)。 視乎程式若設計,若要求程式長駐背景作掃描,Android 10 以上還具要求 Background Location 權限,否則用戶須開 App 才可作掃描到結果。 獲得這些權限的程式,可以長期在背景收集用戶位置,包括 GPS, WiFi 及 流動電話網絡定位。 此外,即使用戶關上電話 GPS 及其他輔助定位功能、單純透過 BLE 定位,由於 BLE 在香港已有很全面的應用,亦能做到很準確的記錄用戶行蹤。 舉例說,所有港鐵月台已安裝 beacon,身在站內或車內作定位用途,即使是地底,已可做到以米計的精確度,亦即是說,你何時、坐哪班港鐵、哪個車卡、從什麼站到什麼站,已可以準確記錄。(順帶一提,安心出行與港鐵App是同一開發商,政府是港鐵大股東,移植相關功能及 beacon 數據,沒有難度。) 不搭港鐵嗎,BLE have you covered。九巴已在其數以千計的巴士站,安裝 beacon,用作車站定位及下車提示。大部份市區主要路段,已被覆蓋。同樣當局若向九巴取得 beacon 標識與巴士站的對應數據,已可追蹤使用者途經市區多個地點的紀錄(注意不一定要搭九巴的)。(順帶一提,新鴻基地產支持政府推出「安心出行」,旗下商場掃「安心出行」可獲贈積分換禮品。新地是載通國際大股東。) 當局選擇小巴作試驗,正是彌補了上述巴士及港鐵涵蓋不足之處,因為尤其是專線小巴,正正是行走一些較遠離市區核心,未有 beacon 的地方。 因此當局若解決了小巴以流動方式安裝 beacon 的判別問題,很容易便可將藍芽定位推廣至大部份公共交通工具。香港九龍新界地面地底無得避。 要公眾接受定位當然是有難度,因此先以看似較少影響的小巴,開始是以自願開啟定位的方式入手,到証實有成效時,才加入新措施全面推廣,是符合當局「按部就班」指導思想的做法。 # 感應大數據 此外,政府與浸會大學正研究以手機「感應位置變化速度」和大數據分析,來判斷用家是否已離開的士,以新增自動離開功能。在 Android 10 以上,這需要 Activity Recognition 權限。這涉及常見的感應器,包括 accelerometers, gravity sensors, gyroscopes, rotational vector sensors, orientation sensors 及 magnetometers,用途廣泛,可以透過監察手機的震動,方向,加速度等的詳鈿數據,用以識別用者的活動,如靜止,步行,乘車,升降機,以至更深入的步速,步行方向,上落樓梯等。此外,每人的步姿都有不同,透過步姿特徵辨識身份也是有可能的。隨着如 deep learning 技術普及和手機 neural network 運算效能提升,這些已不是天馬行空而是已成熟的技術,所以 Google 才為這些由來已久的感應裝置新加入 Activity Recognition 權限,提示用戶有關私隱影響。而 Google 在 Play Service 內亦提供 Activity Recognition API 供辨認基本的用戶活動 [7]。 與其他權限不同,感應器在 Android 10 以下是不能關閉的,在 Android 10 關閉選項(Sensors Off)亦藏在 Developer Options 內,一般用戶未必會找到。 # 總結 以上僅是客觀地列出了「安心出行」一些有跡可尋的發展可能性,以及其私隱影響,以供考慮及自行評估。如果大家相信政府的承諾,資料只會用於抗疫,上述可能性亦不足為懼。相反,對政府抱懷疑態度的公眾,是有相當數量。政府若真心抗疫,要達到全民參與,唯一可做的,就是和很多其他地方一樣,將程序開源讓公眾有效監察,並放上 F-Droid 等開源庫,由獨立可靠的第三方按源碼編繹,保證源碼及程式一致。用立法手段強制使用,將下載數字作為政績,而不同時提高透明度,只是自欺欺人的做法,令部份公眾用各種方式規避,對抗疫沒有好處。 [1] 除非… 「司機唔該跟貼前面架巴士,我要用佢 WiFi 上網」 [2] 全文見新聞稿原文 [3] 即使假設程式要偵測是否正使用 WiFi 連線,以啟動下載,ACCESS_NETWORK_STATE (查看網絡連線)權限已經足夠,「小鴨幹線」便是例子。 [4] CI 相信不是軟件開發的 Continuous Integration,又不似統計方面的 Confidence Interval。 [5] 完全是架床疊屋,原本資料(keyData)已經是所謂加密的 data 加上 base 64 encode,加上 Protobuf ,壓縮空間不大,開發者竟想到用多一次 base 64 encode 發大再用 zip。 [6]資料來源:經濟日報 [7] https://developers.google.com/android/reference/com/google/android/gms/location/ActivityRecognitionClient
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up