swift之保存數據到keychain


訪問KeyChain

1.在mac上按下 Command+Space 輸入Keychain Access

2.在終端輸入security find-generic-password -help

讀取配置文件授權

cd ~/Desktop

//ios產看應用的授權來發現他需要的訪問類型,應用的授權以編碼的形式保存在對應的簽名的配置文件中,嘉定已經創建一個配置文件,名為KeycahinTest_Dev.mobileprovision並且保存在桌面

security cms -D -i KeychainTest_Dev.mobileprovision | grep -A12 “Entitlements” 

 

 

keychain-acess-groups 定義同一開發者開發的應用所共享的鑰匙串群組標識

 

ios應用中使用key-chain

1.引入框架 import Security    修改Build Setting中Capabilities支持

 

使用Touch ID驗證用戶

 

1.引入LocalAuthentication框架

2.創建LAContext類的實例

3.調用LAContext實例的canEvaluatePolicy:(LAPolicyDeviceOwnerAuthenticaitonWithBiometrics)error:方法確認Touch Id是否可用

 

4.Touchid可用則使用LAContext的evaluatePolicy:localizedReason:reply:方法驗證TouchID的用戶

 

import UIKit

import LocalAuthentication

 

class ViewController: UIViewController {

    

    @IBOutlet weak var buttonCheckTouchId: UIButton!

    

    @IBOutlet weak var buttonUseTouchId: UIButton!

    

    override func viewDidLoad() {

        super.viewDidLoad()

        

       

    }

 

    //touchId是否可用

    func checkTouchIdAvailability(sender: AnyObject) {

        let context = LAContext()

        var error: NSError?

        let isTouchIdAvailable = context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error)

        buttonUseTouchId.isEnabled = isTouchIdAvailable

        //Touch ID不可用的

        if isTouchIdAvailable == false {

            let alertController = UIAlertController(title: "Touch Id", message: "TocuhId is not available", preferredStyle: .alert)

            alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))

            present(alertController, animated: true, completion: nil)

        }

        

    }

    @IBAction func userTouchId(sender: AnyObject) {

        let context = LAContext()

        var error: NSError?

        //localizedReason標識在應用中請求用戶提供指紋進行驗證的文本提示內容

        let reason = "please authenticate with Touch id to access your private information"

        context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: reason, reply: { (success: Bool, error: NSError!) in

            if success{

                //用戶已經通過驗證

            }else{

                //用戶為通過驗證

            }

            } as! (Bool, Error?) -> Void)

        

    }

 

}

 

 

 

 

 

在鑰匙串中存儲數據是以鍵值對方式存儲的

kSecCalss    安全存儲字符串數據

kSecClassGenericPassword

kSecAttrService  應用bundle標識字符竄

kSecAttrAcount   存儲數據的對應鍵,可以是任意有意義的字符串

kSecValueData 該鍵的值是一個NSData實例,存放kSecAttrAccount對應的數據

 

OSStatus類型在xcode中Commond+ shilft + O 輸入SecBase 查找errSecSucces,可以看到OSStatus類型

 

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        // Override point for customization after application launch.

       

        return true

    }

    //保存到鑰匙串

    func savetoKeyChain() {

        let key = "Full Name"

        let value = "Steve Jobs"

        let valueData = value.data(using: .utf8, allowLossyConversion: false)

        let service = Bundle.main.bundleIdentifier!

        let secItem = [

            kSecClass as NSString : kSecClassGenericPassword as NSString,

            kSecAttrService as NSString : service,

            kSecAttrAccount as NSString : key,

            kSecValueData as NSString : valueData!

            ] as NSDictionary

        

        var result:CFTypeRef?

        let status = Int(SecItemAdd(secItem, &result))

        switch status {

        case Int(errSecSuccess):

            print("Successfully stored the value")

        case Int(errSecDuplicateItem):

            print("this item is already saved, Cannot duplicate it")

        default:

            print("An error occurred with code\(status)")

        }

    }

    //在鑰匙串中查找數據

    /****查找鑰匙串h中的值

     SecItemCopyMatching(CFDictionary, UnsafeMutablePointer<CFTypeRef?>?)

     1.構建一個字典,天劍kSecClass鍵,設置鍵的值來標識查找項的類型。 例如:kSecClassGenericPassword

     2.添加kSecAttrService鍵。取值為查找項服務的字符串,所有應用應采用相同的值,這樣任意應用寫到鑰匙串的數據,其他應用可以訪問

     3.添加kSecAttrAccount鍵,取值為鑰匙串已存儲項對應的鍵

     4.獲取特定屬性的值:創建修改日期,需要向字典中添加kSecReturnAttributes,並將其值設置為kCFBooleanTrue

     

     如果設置CFDictionary鍵為 kSecReturnAttributes鍵,則返回值為nil或CFDictionaryRef隱含類型

     如果為kSecReturnData添加到字典,返回類型是CDDataRef

     **/

    func queryFromKeyChain(){

        let keyToSearchfor = "Full Name"

        let service = Bundle.main.bundleIdentifier

        let query = [kSecClass as NSString : kSecClassGenericPassword as NSString,

                     kSecAttrAccount as NSString : keyToSearchfor,

                     kSecAttrService as NSString : service,

                     kSecReturnAttributes as NSString : kCFBooleanTrue

            ] as NSDictionary

        var valueAttributes : CFTypeRef?

        let results = Int(SecItemCopyMatching(query, &valueAttributes))

        if results == Int(errSecSuccess) {

            let attributes = valueAttributes! as! NSDictionary

            let key = attributes[kSecAttrAccount as NSString] as! String

            let accessGroup = attributes[kSecAttrAccessGroup as NSString] as! String

            let createDate = attributes[kSecAttrCreationDate as NSString] as! NSDate

            let modifiedDate = attributes[kSecAttrModificationDate as NSString] as! NSDate

            let serviceValue = attributes[kSecAttrService as NSString] as! String

            

        }else{

            print("Error happened with code:\(results)")

        }

        

    }

    func queryDataFromKeyChain(){

        let keyToSearchfor = "Full Name"

        let service = Bundle.main.bundleIdentifier

        let query = [kSecClass as NSString : kSecClassGenericPassword as NSString,

                     kSecAttrAccount as NSString : keyToSearchfor,

                     kSecAttrService as NSString : service,

                     kSecReturnData as NSString : kCFBooleanTrue

            ] as NSDictionary

        var returnedData : CFTypeRef?

        let results = Int(SecItemCopyMatching(query, &returnedData))

        if results == Int(errSecSuccess) {

            let data = returnedData! as! Data

            let value = String(data: data, encoding: .utf8)

            

            

        }else{

            print("Error happened with code:\(results)")

        }

        

    }

    func updateKeyChain() {

        let keyToSearchFor = "Full Name"

        let service = Bundle.main.bundleIdentifier

        let query = [kSecClass as NSString:

                     kSecClassGenericPassword as NSString,

                     kSecAttrService as NSString: service,

                     kSecAttrAccount as NSString : keyToSearchFor,] as NSDictionary

        var result: CFTypeRef?

        let found = Int(SecItemCopyMatching(query, &result))

        if found == Int(errSecSuccess){

            let newData = "Mark tremonti".data(using: .utf8, allowLossyConversion: false)

            let update = [kSecValueData as NSString: newData!,

                          kSecAttrComment as NSString : "my comments"] as NSDictionary

            let updated = Int(SecItemUpdate(query, update))

            if updated == Int(errSecSuccess){

                print("Successfully updated the existing value")

                readExistingValue();

            } else {

                print("failed to update the value. error = \(updated)")

            }

        }else{

            print("error happened. Code=\(found)")

        }

        

    }

    //更新多個值

    func readExistingValue() {

        

        

    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM