Keychain的介紹和使用

什麼是 Keychain?

iOS 的 keychain 服務提供了一種安全的保存私密信息(密碼,序列號,證書等)的方式,每一個ios程序都有一個獨立的keychain存儲。
用於儲存一些私密信息,好比密碼、證書等等,Keychain裏保存的信息不會因App被刪除而丟失,在用戶從新安裝App後依然有效。
一樣也適用於應用之間數據共享。咱們能夠把KeyChain理解爲一個Dictionary,全部數據都以key-value的形式存儲,能夠對這個Dictionary進行add、update、get、delete這四個操做。ios

keychain 的四個方法介紹?

存儲方法

OSStatus SecItemAdd(CFDictionaryRef attributes, CFTypeRef * __nullable CF_RETURNS_RETAINED result)
複製代碼

attributes: 要添加的數據
result: 存儲數據後,返回一個指向該數據的引用,不使用該數據傳入 nilswift

條件查詢方法

OSStatus SecItemCopyMatching(CFDictionaryRef query, CFTypeRef * __nullable CF_RETURNS_RETAINED result)
複製代碼

query: 要查詢數據的條件
result: 查詢到數據的引用安全

數據更新方法

OSStatus SecItemUpdate(CFDictionaryRef query, CFDictionaryRef attributesToUpdate)
複製代碼

query: 要更新數據的查詢條件
attributesToUpdate: 要更新的數據bash

刪除數據方法

OSStatus SecItemDelete(CFDictionaryRef query)
複製代碼

query: 要刪除數據的查詢條件app

使用 Keychain

使用 Keychain 首先須要導入安全框架 secutity.framework框架

建立查詢條件

class func createQuaryMutableDictionary(identifier: String)->NSMutableDictionary{
    // 建立一個條件字典
    let keychainQuaryMutableDictionary = NSMutableDictionary.init(capacity: 0)
    // 設置條件存儲的類型
    keychainQuaryMutableDictionary.setValue(kSecClassGenericPassword, forKey: kSecClass as String)
    // 設置存儲數據的標記
    keychainQuaryMutableDictionary.setValue(identifier, forKey: kSecAttrService as String)
    keychainQuaryMutableDictionary.setValue(identifier, forKey: kSecAttrAccount as String)
    // 設置數據訪問屬性
    keychainQuaryMutableDictionary.setValue(kSecAttrAccessibleAfterFirstUnlock, forKey: kSecAttrAccessible as String)
    // 返回建立條件字典
    return keychainQuaryMutableDictionary
}
複製代碼

存儲數據

class func keyChainSaveData(data: Any ,withIdentifier identifier:String)-> Bool {
    // 獲取存儲數據的條件
    let keyChainSaveMutableDictionary = self.createQuaryMutableDictionary(identifier: identifier)
    // 刪除舊的存儲數據
    SecItemDelete(keyChainSaveMutableDictionary)
    // 設置數據
    keyChainSaveMutableDictionary.setValue(NSKeyedArchiver.archivedData(withRootObject: data), forKey: kSecValueData as String)
    // 進行存儲數據
    let saveState = SecItemAdd(keyChainSaveMutableDictionary, nil)
    if saveState == noErr  {
        return true
    }
    return false
}
複製代碼

更新數據

class func keyChainUpdata(data: Any ,withIdentifier identifier:String)->Bool {
    // 獲取更新的條件
    let keyChainUpdataMutableDictionary = self.createQuaryMutableDictionary(identifier: identifier)
    // 建立數據存儲字典
    let updataMutableDictionary = NSMutableDictionary.init(capacity: 0)
    // 設置數據
    updataMutableDictionary.setValue(NSKeyedArchiver.archivedData(withRootObject: data), forKey: kSecValueData as String)
    // 更新數據
    let updataStatus = SecItemUpdate(keyChainUpdataMutableDictionary, updataMutableDictionary)
    if updataStatus == noErr {
        return true
    }
    return false
}
複製代碼

查詢數據

class func keyChainReadData(identifier: String)-> Any {
    var idObject:Any?
    // 獲取查詢條件
    let keyChainReadmutableDictionary = self.createQuaryMutableDictionary(identifier: identifier)
    // 提供查詢數據的兩個必要參數
    keyChainReadmutableDictionary.setValue(kCFBooleanTrue, forKey: kSecReturnData as String)
    keyChainReadmutableDictionary.setValue(kSecMatchLimitOne, forKey: kSecMatchLimit as String)
    // 建立獲取數據的引用
    var queryResult: AnyObject?
    // 經過查詢是否存儲在數據
    let readStatus = withUnsafeMutablePointer(to: &queryResult) { SecItemCopyMatching(keyChainReadmutableDictionary, UnsafeMutablePointer($0))}
    if readStatus == errSecSuccess {
    if let data = queryResult as! NSData? {
        idObject = NSKeyedUnarchiver.unarchiveObject(with: data as Data) as Any
    }
    }
    return idObject as Any
}
複製代碼

刪除數據

class func keyChianDelete(identifier: String)->Void{
    // 獲取刪除的條件
    let keyChainDeleteMutableDictionary = self.createQuaryMutableDictionary(identifier: identifier)
    // 刪除數據
    SecItemDelete(keyChainDeleteMutableDictionary)
}
複製代碼

簡單應用

獲取 UUID

直接獲取 UUID 每次卸載從新安裝 app 後可能會致使 UUID 變化,爲了獲取惟一的 UUID,咱們使用 keyChian 對 UUID 進行保存ide

class func getUUID() -> String {
    if let uuid = QWUUIDTools.keyChainReadData(identifier: "key") as? String {
        return uuid
    }else {
        if let uuid = UIDevice.current.identifierForVendor?.uuidString {
            if QWUUIDTools.keyChainSaveData(data: uuid, withIdentifier: "key") {
                return uuid
            }
        }
    }
    return "simulator"
}
複製代碼
相關文章
相關標籤/搜索