Keychain
keychain是一個database,每個key-value pairs稱為一個keychain item,所有的values都加密過,特別適合用來儲藏小size的user secrets。Keychain需要link ios Security.framework,我們的application透過SecItem API來存取keychain items:
app process透過SecItem API把我們的request丟給另一個process "securityd",這算是一個中間人,因為他雖然可以query Keychain database,但是並沒有decrypt keychain value的能力,所以"securityd"會再把這個encrypted value丟到Apple A7+ chip上面的硬體security code processor稱為 Secure enclave,由此module決定是否要decrypt。
Keychain安全性
1. 被使用者iphone密碼保護2. 被使用者iphone 出廠設定的unique device secret保護
3. keychain只有當使用者解鎖之後才能access
4. access control (只有儲存data的app能access自己的data)
總之Keychain是Apple保護某個on disk的secrets的功能,我們可以確信此protection是安全的,但是我們application的責任就是:不能把解密過後的secrets長期放到memory中(e.g. global/static variables),或是透過網路傳送。
SecItem APIs
SecItem是C API:Data protection classes
Keychain裡面的item能否被access,藉由設定以下幾種可能的protection profiles給kSecAttrAccessible attribute:包括以下幾種(詳見api document說明):
但是以上幾種不能確定使用者到底有沒有設定device passcode,除非使用以下:
上面這個protection class 是說keychain只有當user authenticate之後才能access,而且當user lock device之後就不能access。當passcode被移除的話,在Secure enclave上的passcode secret就會被移除,所以再也無法解密被保護的items。
Keychain Access Control List (ACL)
每當app要access被ACL和touch id保護的keychain item的時候,以下這個畫面就會跳出來:
1. authentication,藉由policy control:
2. item accessibility
Touch ID Authentication
touch ID可以用來當作authenticate,用來驗證可否存取keychain裡面的item,安全性來自Secure enclave,所有的touch id data都存放在secure enclave中,而且所有的touch id operations都在secure enclave中完成,即便OS kernel被compromised也不影響其安全性,因為是一個sandbox。Secure enclave如果發現touch id數次驗證未過的話,就會強制只能透過device passcode authenticate,重新輸入device passcode之後就能恢復使用touch id authentication。
注意keychain key operations也是在secure enclave中完成,所以跟touch id搭配是非常適合的。
使用ACL來進行touch id authentication是由LocalAuthentication framework提供API來讓application使用:
Code Example
儲存secrets: 原本沒有ACL control的keychain storage如下如果我們加上ACL control:
讀取secrets
SecItemCopyMatching會啟動LocalAuthentication 功能,所以系統的指紋辨試或是passcode輸入畫面就會出現。不過為了不要block main thread,這個SecItemCopyMatching最好是放到global queue中。
沒有留言:
張貼留言