访问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() {

}

swift之保存数据到keychain的更多相关文章

  1. EasyUI使用JSON保存数据

    目前来说,使用JSON保存数据比较方便,前台可以不用Test.aspx 页面,可以直接用Html页面,使用.aspx页面的弊端就不在这里熬述. 具体步骤如下: 1.新建一个Html页面,命名为Test ...

  2. AC中保存数据与查询数据

    //保存数据 hui.ajax(function (ret, err) { }, url, {values: {t:"test",m:"Search",c:&q ...

  3. SpringMVC保存数据到mysql乱码问题

    SpringMVC保存数据到mysql乱码问题 乱码问题常见配置 一.web.xml配置过滤器 <filter> <filter-name>encoding-filter< ...

  4. Android开发学习---android下的数据持久化,保存数据到rom文件,android_data目录下文件访问的权限控制

    一.需求 做一个类似QQ登录似的app,将数据写到ROM文件里,并对数据进行回显. 二.截图 登录界面: 文件浏览器,查看文件的保存路径:/data/data/com.amos.datasave/fi ...

  5. android fragment 的用法以及与activity的交互和保存数据的方法,包括屏幕切换(转载)!

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/37992017 1.管理Fragment回退栈 类似与Android系统为Acti ...

  6. Post model至Web Api创建或是保存数据

    前一篇<Post model至Web Api>http://www.cnblogs.com/insus/p/4343538.html中,使用Post来从Web Api获取数据.由于Post ...

  7. SharedPreferences保存数据

    1.使用SharedPreferences保存数据方法如下: //实例化SharedPreferences对象(第一步) SharedPreferences mySharedPreferences= ...

  8. Android 分享一个SharedPreferences的工具类,方便保存数据

    我们平常保存一些数据,都会用到SharedPreferences,他是保存在手机里面的,具体路径是data/data/你的包名/shared_prefs/保存的文件名.xml, SharedPrefe ...

  9. mysql保存数据提示1366 Incorrect string value: ‘\xF0\x9F\x98\x8A\xF0\x9F…’ 解决

    在保存数据时我们如果页面编辑与数据库字段编码不一样或字符集超出你了mysql数据库中的字符类型就有可能出一\\xF0\\x9F\\x98\\x8A\\xF0\\x9F提示了,下面我来简单的解决方法. ...

随机推荐

  1. js获取cookie提取用户名asp.net+html

    JavaScript是运行在客户端的脚本,因此一般是不能够设置Session的,因为Session是运行在服务器端的. 而cookie是运行在客户端的,所以可以用JS来设置cookie. 假设有这样一 ...

  2. NO18 linux开机自启动设置--开机流程--中文乱码--查看行数

    第八题:装完系统后,希望让网络文件共享服务NES,仅在3级别上开机自启动,该如何做? 解答:什么是开机自启动,在Linux下软件服务随系统启动而启动的配置. 方法一:文件配置法,可以把要启动的服务的命 ...

  3. WINccflexiable2008 的水箱控制上位机HMI仿真

    步骤1 将PLC程序编写完成,CPU为314-2DP 符号表中的符号可以被所有逻辑块调用 步骤2 组态PLC300与西门子触摸屏170系列 TP177B CLOLOR PN/DP的MPI通信. 步骤3 ...

  4. 运行自己的 DaemonSet【转】

    本节以 Prometheus Node Exporter 为例演示如何运行自己的 DaemonSet. Prometheus 是流行的系统监控方案,Node Exporter 是 Prometheus ...

  5. KAZE特征和各向异性扩散滤波

    kaze feature: http://www.doc88.com/p-6911376909693.html 各向异性扩散滤波  Scale-space and edge detection usi ...

  6. 51nod 1163:最高的奖励 优先队列

    1163 最高的奖励 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题  收藏  关注 有N个任务,每个任务有一个最晚结束时间以及一个对应的奖励.在结束时间之前完成该 ...

  7. app1----攻防世界

    啥也不说把题目下载下来,在模拟器里运行一下 输入正确的key就是flag 继续下一步分析,可以使用Androidkiller分析,我喜欢使用jeb这里我就使用jeb进行分析 找到MainActivit ...

  8. springboot自定义属性文件与bean映射注入属性值

    主要有几点: 一.导入依赖 springboot的包和: <dependency> <groupId>org.springframework.boot</groupId& ...

  9. android中的简单animation(一)shake

    1.shake animation_1.xml: <?xml version="1.0" encoding="utf-8"?> <Linear ...

  10. 修正png

    这是修正+取MD5的方法 function MD5FileTextPng(filename: AnsiString): AnsiString; var buf: ..MAX_PATH - ] of C ...