• 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() {

            

            

        }

  • 相关阅读:
    nginx构建https
    安装mysql的遇到的问题
    docker mysql 2059
    centos7 安装chrome
    谷歌浏览器启动参数
    php-webdriver:PHP控制浏览器动作, php web驱动, PHP实现自动化, php webdriver 教程, A php client for webdriver.
    nginx转发
    nginx变量与实列
    mysql 语句
    frp 内网穿透配置
  • 原文地址:https://www.cnblogs.com/sundaysme/p/10362400.html
Copyright © 2020-2023  润新知