在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
访问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() {
}
|
请发表评论