iOS Keychain 同步服務
加密機制探討
2020-9-1 高田數位鑑識
Keychain 是 Apple 生態系統的主要功能之一。 Keychian 包含太多的敏感資訊,因此在 iOS 內也是受到最嚴格安全機制的保護。 同時,鑑識領域對於 Keychain 的開發還相對不足。 眾所周知,Keychain 包含用戶的帳號與密碼,以及支付工具的資料,如信用卡。除了以上資訊之外,Keychain 實際上還包含成千上萬個屬於各種 App 和系統的資訊,這些資訊是開啟許多其他敏感 App 內的內容所必需的鑰匙。 本文章會就 Keychain,其內容、保護與同步機制方法做深入的探討。
如何啟用 iCloud Keychain
現在的生活型態使用者同時擁有多台 Apple 裝置,如 MacBook,iPad,iPhone 等是常見的情況,為了增加使用者體驗,啟用了 iCloud Keychain 服務可大幅降低在不同裝置存取同樣的網站或 App 重複輸入身分驗證的問題。如何啟用 iCloud Keychain 可參考官方說明。
新增一組密碼至 Keychain – 開發者視角
Keychain 採用「鍵-值資料庫」(Key-Value Pair)型態儲存資料,並提供一個簡單,安全的儲存服務與空間來存放使用者與 App 相關的重要資訊。藉由這個服務,可以避免反覆詢問使用者輸入密碼,開發者也不必建置自己的加密保護機制,除了很容易出錯,加密等級也無法同等於 Secure Enclave 所提供的安全機制。以下為將密碼加入至 Keychain 的程式範例。
程式碼一、Keychain Add Query
從第三行 KSecClass 屬性可看出該密碼屬於 Internet 密碼(kSecClassInternetPassword),Keychain 服務從中推斷出該資訊需要加密。但是,Keychain 的功能遠不止儲存密碼。 App 可以使用 Keychain 服務來儲存身分認證憑證(Identity),身份認證 Token(Authentication Token),加密密鑰(Encryption Key)與憑證(Certificate)等不同項目類別(Class)的資料。
以下為 Keychain 可儲存的主要類別與值(Class & Key) ,更詳細的內容可在 Apple 開發文件中了解 Keychain 服務的方式。
Item Class Keys 為 kSecClass 所包含的值(Value)的類別:
項目 | Item Class Values | 說明 |
---|---|---|
1 | k |
通用密碼。 |
2 | k |
網路密碼。 |
3 | k |
憑證,憑證內會有公鑰。 |
4 | k |
密鑰,也是所謂的私鑰。 |
5 | k |
該值包含一個「憑證」和一個「私鑰」。 |
表一、Item Class Keys 「kSecClass 」and Values
可檢視與不可檢視的 Keychain
Keychain 的可被使用者檢視的是密碼。 當在 Safari 瀏覽網站被要求輸入帳號與密碼時,iOS 會提示使用者是否要紀錄在 Safari 中輸入的帳密。 Safari 和 App 均可使用密碼自動輸入服務。 使用者也可以透過「設定」、「密碼和帳號」、「網站與 App 密碼」來檢視已存儲的密碼。
使用者不可檢視(但 iOS 開發人員可以存取)的是憑證,密鑰和信任服務。 憑證和身分認證憑證可確保資料僅被驗證過的使用者取用,主要用於保護他人想要假冒原使用者的身份。 加密密鑰用於加密,數位簽章與資訊驗證。
圖一、Keychain 服務 API
除了密碼之外幾乎所有其他內容都無法通過 GUI 檢視或以其他方式查看。 儲存在 Keychain 的資料可被系統和 App 檢視的項目如下:
- Authentication Token: 這些 Token 用於自動驗證使用者是否有合法存取雲端的服務,過程無需再次輸入帳號與密碼。 透過提取身份認證 Token,鑑識同仁可以在無需輸入帳號密碼的情況下存取某些使用者線上帳號,且在適用的情況下跳過雙重驗證(two-factor authentication)程序。 例如,您可以使用提取的 Token 登入 Facebook,Google 帳號或其他線上服務。
- Shared Secrets: 一次性驗證碼(TOTP)相容的身份驗證 App(例如 Microsoft Authenticator 或 Google Authenticator)使用的加密種子。
- Encryption Keys: 用於加密和解密重要資訊,例如第三方密碼管理器使用的密碼資料庫。
- Certificates and identities: 憑證與身分認證憑證。
iCloud Keychain 同步服務
Apple 生態系統提供了一個在裝置之間同步 Keychain 資料的簡便方法。該服務的名稱為 iCloud Keychain。iCloud Keychain 服務可透過 iCloud 同步 kSecAttrSynchronizable 屬性為 YES 的 keychain 資料。 如果已啟用了 iCloud Keychain,當用戶在新裝置透過 iCloud Keychain 服務同步時會自動收到所有 Safari 與 App 的密碼資訊。 請注意,密碼以外的許多其他資料(例如加密密鑰,憑證與信用卡)若未將屬性標記 kSecAttrSynchronizable 為 YES,將不會同步到新裝置。 需注意的是,密碼以外的重要資料仍包含在 iTunes 與 iCloud 備份內。 只是這些資料在做加密保護處理時,除了 Passcode 外,若有啟用 ThisDeviceOnly 的保護屬性,備份產生時還會使用設備硬體 UID 做加密保護,故只能回復到備份它們的同一物理裝置上(相同的硬體 UID)。
因此以下屬性與參數會決定資料是否會同步到 iCloud Keychain,而透過 iTunes 備份和 iCloud Backup 是否可回復到其他新的裝置上,或是可被提取出:
- ThisDeviceOnly:
- 若在 Keychain 內的資訊有啟用該屬性,不會同步到 iCloud Keychain。
- iTunes 與 iCloud Backup 會包含該資訊,但會採用裝置硬體 UID 加密保護,所以無法還原到其他物理裝置上。
- WhenPasscodeSetThisDeviceOnly:
- 不會同步到 iCloud Keychain。
- 只有在啟用螢幕密碼的情況下,該 Keychain 保護的內容才可藉由備份回復到原裝置。
- 如果刪除螢幕密碼,則解開 WhenPasscodeSetThisDeviceOnly 的金鑰也會刪除,故資料無法開啟。
- 若使用者沒有設定螢幕密碼,啟用該屬性的項目 Keychain 也不會儲存用戶輸入的密碼。
- 因採用硬體 UID 保護,具有此屬性的項目永遠不會移轉到新裝置。
- 將備份還原到新裝置後,這些 Keychain 項目也不會出現。
- kSecAttrSynchronizable:
- 如果啟用此設定,在 Keychain 內資料屬性為 Yes 的 kSecAttrSynchronizable 將同步到 iCloud Keychain 服務上。
- 可同步到其它的 Apple 裝置上。
- 若資料的 kSecAttrSynchronizable 沒設定,該資料還是會包含在 iTunes 與 iCloud Bakcup 中,只是這些資料會另外用裝置硬體 UID 保護,未來只能回復到產生該備份的裝置上。
- iTunes backup password:
- 如果在產生備份之前設置了 iTunes backup Password 密碼,沒有設定 ThisDeviceOnly 屬性的 keychain 項目將使用該備份密碼進行加密。最重要的是,由 iTunes Backup Password 所保護的資訊可以被提取和解密。若不知備份密碼的情況下也可採暴力破解。
- 若 Keychain 內的項目的 ThisDeviceOnly 屬性有設定,原本由 iTunes backup password 所保護的資料會改由裝置硬體的 UID 進行了加密保護,這使它們在原始裝置以外的任何裝置皆無法解開該資訊。
- 若無設定 iTunes backup password ,未加密的備份會將 Keychain 內所有項目都改用裝置硬體 UID 進行加密,這代表整個 Keychain 除了原始產生備份的裝置外,任何其它地方,新的裝置都無法將開 Keychain 內容解開。
Keychain 資料保護與螢幕鎖狀態
在 Apple 開發文件的「Keychain 資料保護概述」內,Apple 透過 kSecAttrAccessible 屬性為不同類型的 Keychain 項目定義了可用的保護類別。 此屬性根據螢幕鎖的狀態,控制 Keychain 項目的可用性。
注意:沒有密碼的裝置被視為始終處於解鎖狀態,因此存儲在下列前三個屬性中的 Keychain 項目不再受到任何保護。
- Always Available (Before First Unlock): 即使裝置已上鎖或處於「首次解鎖之前 – Before First Unlock」狀態,啟用 kSecAttrAccessibleAlways 屬性的 Keychain 項目始終可被系統或 App 讀取。 在 BFU 提取過程中,只有啟用此保護類別的項目才可以被提取。 Apple 不建議將此保護等級用於 App。 使用 iTunes 加密備份時,具有此屬性的項目可移轉到新裝置。
- After First Unlock一旦使用者在重新啟動後並輸入螢幕鎖鎖密碼解開裝置,就會處於「首次解鎖後 – After First Unlock」狀態。 如果裝置沒有密碼,則也滿足此條件。 在重新啟動裝置之前,AFU 狀態保持為 true。 kSecAttrAccessibleAfterFirstUnlock 屬性通常會用於需要在背景更新資料的 App。 標準的 iOS 開發程式人員應將此保護類別用於需在背景持續更新資料的 App。
- When Unlocked: kSecAttrAccessibleWhenUnlocked 屬性使 Keychain 項目僅在裝置解鎖或沒有密碼時才可被存取。未明確指定保護等級時,這是預設的屬性設定。
- When Passcode Is Set – This Device Only: 這是可用的最高層級的保護屬性。 使用 kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly 屬性所儲存的項目的行為具有類似 kSecAttrAccessibleWhenUnlocked 屬性。 但是,它們僅在裝置設定了螢幕所密碼後才可使用。 據 Apple 所稱,此類項目:
-
- 不會同步到 iCloud Keychain
- 不會備份到 iTunes 與 iCloud Backup (這是唯一一個不會被備份的保護屬性)
- 不包含在 Escrow Keybag (第三方託管 Keybag)
只要螢幕鎖移除後,受該類別保護的金鑰也立即移除,資料無法被存取。
-
- This Device Only: 在所有類型的備份中,結尾有標記 ThisDeviceOnly 屬性的 Keychain 項目會受到裝置硬體的 UID 保護,如果嘗試回復到其他裝置,該屬性的項目皆無法回復。
- 不會同步到 iCloud Keychain。
- 會包含在 iCloud Backup,但因收到硬體 UID 保護,無法移轉到其它裝置。
- 會包含在 iTunes Backup,但因收到硬體 UID 保護,無法移轉到其它裝置。
以下整理了保護類別與 ThisDeviceOnly 的可用組合完整列表:
- Always:
- kSecAttrAccessibleAlways 與 kSecAttrAccessibleAlwaysThisDeviceOnly
- After First Unlock:
- kSecAttrAccessibleAfterFirstUnlock 與 kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
- When Unlocked:
- kSecAttrAccessibleWhenUnlocked 與 kSecAttrAccessibleWhenUnlockedThisDeviceOnly
- When Passcode is Set
- 只有 kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
最高保護級別(WhenPasscodeSet)僅與 ThisDeviceOnly 結合使用。此類項目絕不會轉移到其它裝置,並且如果從裝置中刪除了螢幕鎖密碼,這些項目立刻無法被存取。
「始終可存取 – Always Accesible」為最低無保護類別,自 iOS 9 開始已被列為棄用 (deprecated )。 已被棄用的保護類別若開發者選擇使用主要是為了向下相容舊有的 iOS 版本與裝置。 該保護類別是 BFU 狀態下可提取少數 Keychain 資料的原因之一。
iOS 加密機制文章