iOS数据存储-钥匙串存储

2017.11.20 14:41* 字数 227 阅读 678评论 0喜欢 0

  • 钥匙串介绍

    1. 表示设备唯一号的标识,在IOS7中要么被禁止使用,要么重新安装程序后两次获取的标识符不一样。

  • 2. 由于IOS系统存储的数据都是在sandBox里面,一旦删除App,sandBox也不复存在。好在有一个例外,那就是keychain(钥匙串)。
  • 3. 通常情况下,IOS系统用NSUserDefaults存储数据信息,但是对于一些私密信息,比如密码、证书等等,就需要使用更为安全的keychain了。
  • 4. 需要导入Security.framework 和KeychainItemWrapper文件;
  • 1.KeychainItemWrapper是apple官方例子“GenericKeychain”里一个访问keychain常用操作的封装类,
  • 2.在官网上下载了GenericKeychain项目后,把“KeychainItemWrapper.h”和“KeychainItemWrapper.m”拷贝到我们项目
  • KeychainItemWrapper下载地址

钥匙串使用

// 引入Security.framework 和KeychainItemWrapper头文件

// 下面两行代码用来标识一个Item

KeychainItemWrapper *keychain=[[KeychainItemWrapper alloc] initWithIdentifier:@"xxxxxx" accessGroup:nil];//xxxx 自定义

[keyWrapper setObject:@"myChainValues" forKey:(id)kSecAttrService];

// 保存账号和密码信息

[keyWrapper setObject:[usernameTextField text] forKey:(id)kSecAttrAccount];

[keyWrapper setObject:[passwordTextField text] forKey:(id)kSecValueData];

// 读取账号和密码信息

// [usernameTextField setText:[keyWrapper  objectForKey:(id)kSecAttrAccount]];

// [passwordTextField setText:[keyWrapper objectForKey:(id)kSecValueData]];

钥匙串(KeyChain)保存和获取用户名和密码

https://www.jianshu.com/p/4d8adcac7e5c

2016.05.07 15:24* 字数 1698 阅读 5873评论 3喜欢 5

苹果推荐的就是使用IDFA、IDFV

idfa: 适用于对外:例如广告推广,换量等跨应用的用户追踪等

idfv: 适用于对内:例如分析用户在应用内的行为等

idfa:主要用于广告,可能会获取不到,iOS用户也可以--> 设置|隐私|广告追踪,里重置此id的值,虽然玩家一般不会重置,但是上述理由已经不足以把idfa作为账号了

idfv: 顾名思义,是给Vendor标识用户用的,每个设备在所属同一个Vender的应用里,都有相同的值。其中的Vender是指应用提供商,但准确点说,是通过BundleID的DNS反转的前两部分进行匹配,如果相同就是同一个Vender,例如对于

com.company.appone,

com.company.apptwo

这两个BundleID来说,就属于同一个Vendor,共享同一个idfv的值。和idfa不同的是,idfv的值是一定能取到的,所以非常适合于作为内部用户行为分析的主id,来标识用户,替代OpenUDID。

转载:http://www.myexception.cn/ai/1985348.html

idfv(identifierForVendor)是CFBundleIdentifier(反转DNS格式)的前两部分。比如某个应用的bundle id 是com.companyName.appname,那么idfv就是com.companyName。来自同一个运营商的应用运行在同一个设备上,此属性的值是相同的;不同的运营商应用运行在同一个设备上值不同,或者同一个运营商的应用运行在不同的设备上值不同。

经测试,只要设备上有一个tencent的app,重新安装后的identifierForVendor值不变,如果tencent的app全部删除,重新安装后的identifierForVendor值改变。

肯定不能将idfv存入NSUserDefaults,因为一旦应用被卸载,那么数据将不复存在,idfv有可能就会改变。keychain不会这样。那么介绍下keychain:

我们可以把KeyChain理解为一个Dictionary,所有数据都以key-value的形式存储,可以对这个Dictionary进行add、update、get、delete这四个操作。对于每一个应用来说,KeyChain都有两个访问区,私有区和公共区。私有区是一个sandbox,本程序存储的任何数据都对其他程序不可见。而要想在将存储的内容放在公共区,需要先声明公共区的名称,官方文档管这个名称叫“keychain access group”,声明的方法是新建一个plist文件,名字随便起,内容如下:

“yourAppID.com.yourCompany.whatever”就是你要起的公共区名称,除了whatever字段可以随便定之外,其他的都必须如实填写。这个文件的路径要配置在 Project->build setting->Code Signing Entitlements里,否则公共区无效,配置好后,须用你正式的证书签名编译才可通过,否则xcode会弹框告诉你code signing有问题。所以,苹果限制了你只能同公司的产品共享KeyChain数据,别的公司访问不了你公司产品的KeyChain。

iOS的keychain服务提供了一种安全的保存私密信息(密码,序列号,证书等)的方式,每个ios程序都有一个独立的keychain存储。相对于NSUserDefaults、文件保存等一般方式,keychain保存更为安全,而且keychain里保存的信息不会因App被删除而丢失,所以在重装App后,keychain里的数据还能使用。

在应用里使用使用keyChain,我们需要导入Security.framework ,keychain的操作接口声明在头文件SecItem.h里。直接使用SecItem.h里方法操作keychain,需要写的代码较为复杂,为减轻咱们程序员的开发,我们可以使用一些已经封装好了的工具类,apple官方提出了两个工具类:KeychainItemWrapper和SFHFKeychainUtils。

1.使用KeychainItemWrapper

把KeychainItemWrapper下载下来,然后将“KeychainItemWrapper.h”和“KeychainItemWrapper.m”拷贝到我们项目,并导入Security.framework

下面是我在appDelegate.m中的代码:因为我不需要在应用间共享keychain中的内容,所以accessGroup设置为nil

- (NSString *)getIdfv

{

NSString *str;

KeychainItemWrapper *keychainItem = [[KeychainItemWrapperalloc]initWithIdentifier:@"UUID"accessGroup:nil];

MYLog(@"%@",[keychainItem objectForKey:(__bridgeid)kSecValueData]);

NSString *uuidStr = [keychainItemobjectForKey:(__bridgeid)kSecValueData];

MYLog(@"%@",[[UIDevice currentDevice] identifierForVendor]);

if ([uuidStrisKindOfClass:[NSDictionaryclass]])

{ //代表里面还没有存值

NSString *myUUIDStr = [[[UIDevicecurrentDevice] identifierForVendor]UUIDString];

[keychainItem setObject:myUUIDStrforKey:(__bridgeid)kSecValueData];

str = myUUIDStr;

}

else{

str = [keychainItem objectForKey:(__bridgeid)kSecValueData];

}

MYLog(@"======%@",str);

return str;

}

2.SSKeyChains

SSKeyChains对苹果安全框架API进行了简单封装,支持对存储在钥匙串中密码、账户进行访问,包括读取、删除和设置。SSKeyChain的作者是大名鼎鼎的SSToolkit的作者samsoffes。

项目地址:https://github.com/samsoffes/sskeychain

在工程中加入SSKeyChain

在工程中加入Security.framework框架。

把SSKeychain.h和SSKeychain.m加到项目文件夹。

使用SSKeyChain

通过以下类方法来使用SSKeyChain(请查看SSKeyChain.h):

  • (NSArray *)allAccounts;
  • (NSArray *)accountsForService:(NSString *)serviceName;
  • (NSString *)passwordForService:(NSString *)serviceNameaccount:(NSString *)account;
  • (BOOL)deletePasswordForService:(NSString *)serviceNameaccount:(NSString *)account;
  • (BOOL)setPassword:(NSString )password forService:(NSString)serviceName account:(NSString *)account;

文档

在Xcode中安装SSKeyChain的帮助文档需要以下步骤:

打开菜单 Xcode -> Preferences

选择 Downloads

选择 Documentation

点击底部的加号按钮,并输入以下URL: http://docs.samsoff.es/com.samsoffes.sskeychain.atom

点击”SSKeyChain Documentation”旁边的install按钮。 (如果你看不到它,也没有提示任何错误,请重启Xcode)

确保在Organizer中可选的docset中能够看到SSKeychain。

此外,可以在线查看SSKeychain Documentation

调试

如果无法保存钥匙串,请使用SSKeychain.h中提供的错误代码,例如:

NSError *error = nil;

NSString *password = [SSKeychainpasswordForService:@"MyService" account:@"samsoffes"error:&error];

if ([error code] == SSKeychainErrorNotFound) {

NSLog(@"Passwordnot found");

}

显然,你对做这个应该很熟悉了。访问钥匙串是件痛苦的事情,你要随时检查它的每个错误和失败。SSKeychain并没有使它(钥匙串)变得更稳定,它仅仅是繁琐的C APIs封装。

示例代码

保存一个UUID字符串到钥匙串:

CFUUIDRef uuid = CFUUIDCreate(NULL);assert(uuid != NULL);CFStringRef uuidStr = CFUUIDCreateString(NULL, uuid);

[SSKeychain setPassword: [NSString stringWithFormat:@"%@", uuidStr]

forService:@"com.yourapp.yourcompany"account:@"user"];

然后,从钥匙串读取UUID:

NSString *retrieveuuid = [SSKeychainpasswordForService:@"com.yourapp.yourcompany"account:@"user"];

注意: setPasswordpasswordForSevice方法中的services 和 accounts 参数应该是一致的。

3.SFHFKeychainUtils

SFHFKeychainUtils密码保护,使用方法很简单

下载地址:https://github.com/ldandersen/scifihifi-iphone/tree/master/security

1、引入Security.frameWork框架。

2、引入头文件:SFHKeychainUtils.h.

3、存密码:

[SFHFKeychainUtils storeUsername:@"dd"

andPassword:@"aa"

forServiceName:SERVICE_NAME

updateExisting:1

error:nil];

[SFHFKeychainUtils deleteItemForUsername:@"dd"

andServiceName:SERVICE_NAME

error:nil];

4、取密码:

NSString *passWord =  [SFHFKeychainUtils getPasswordForUsername:@"dd"

andServiceName:SERVICE_NAME

error:nil];

keychain的作用:keychain,相当于MAC OS中的钥匙串,但在iOS中相对于功能非常简单.在iOS开发中如果写数据到手机沙盒中,但不管是Caches 还是NSUserDefaults 当应用删除时所有数据都会清除.如果你想在应用删除后还保存一些信息在手机里,这时就要用过keychain了.#import<Security/Security.h> //keychain 管理的类keychain的使用一(原生):

如果使用apple自带操作有以下四个 (增删改查)方法 C语言的

OSStatus SecItemCopyMatching(CFDictionaryRef query, CFTypeRef *result);

OSStatus SecItemAdd(CFDictionaryRef attributes, CFTypeRef *result);

KeyChain中的ItemOSStatus SecItemUpdate(CFDictionaryRef query, CFDictionaryRef attributesToUpdate);

KeyChain中的ItemOSStatus SecItemDelete(CFDictionaryRef query)

keychain的使用二(三方框架 KeychainItemWrapper):

KeychainItemWrapper  就两个文件(KeychainItemWrapper.h  KeychainItemWrapper.m) 苹果开发者中心可以下载 下载地址:KeychainItemWrapper 封装好的OC面向对象.但是代码是MRC的,搞起来不方便,所以没有仔细研究.有兴趣的可以自已去研究下功能还是挺多的.keychain的使用三(三方框架 SFHFKeychainUtils)

下载地址: SFHFKeychainUtils相对于 KeychainItemWrapper 使用起来很方便 ,而且还是ARC的如下提供四个方法:

+ (NSString *) getPasswordForUsername: (NSString *) username andServiceName: (NSString *) serviceName error: (NSError **) error;

+ (BOOL) storeUsername: (NSString *) username andPassword: (NSString *) password forServiceName: (NSString *) serviceName updateExisting: (BOOL) updateExisting error: (NSError **) error;

+ (BOOL) deleteItemForUsername: (NSString *) username andServiceName: (NSString *) serviceName error: (NSError **) error;

+ (BOOL) purgeItemsForServiceName:(NSString *) serviceName error: (NSError **) error;

保存: 通过.userName serviceName 保存一个密码

self.userName = @"[email protected]";

self.userPassword = @"1234567890";

self.serviceName = @"space.kylin.www";

NSError *error;

BOOL saved = [SFHFKeychainUtils storeUsername:self.userName andPassword:self.userPassword

forServiceName:self.serviceName updateExisting:YES error:&error];

读取:通过.userName serviceName 读取一个密码_label.text = [SFHFKeychainUtils getPasswordForUsername:self.userName andServiceName:self.serviceName error:nil];删除:userName serviceName 删除一个密码[SFHFKeychainUtils deleteItemForUsername:self.userName andServiceName:self.serviceName error:nil];清空: 通过一个serviceName清空里面所有数据[SFHFKeychainUtils purgeItemsForServiceName:self.serviceName error:nil];通过keychain我们可以做到保存一数据到手机,不管手机是否删除了该应用.或者系统更新了.我们保存的数据都不会丢失APP之间如何共享keychain数据

以下操作   请在真机上进行调试之前查看了网上相关的资料,发现并没有完整且简单的方法.有些就文字描述了下,有些配了图.但方法是旧的现在也用不了.搞了半天也没有搞定.后天自已看了苹果的开发文档,苹果开发文档写的也比较简单.并没有一步一步列举出来.结合了之前网上一些资料加入苹果开发文档内容,再通过自己的验证终于成功了!首先他建一个工程 :saveKeyChain 打开target 在keychain Groups 里添加你要分享的另一个APP的bundle ID 格式为 XXXXX.com.kylin610.www.另一个工程名   其中 XXXXX 是的你开发者ID (不是apple ID的登陆名哦) 如:123456RVYVD

实际上当你打开keychain Sharing 里project会多出一下文件

打开一看如下 实现就是一个PLIST文件 这里保存你你需要分享APP的bundle ID 也就是上面keychain Groups 里面的信息.两个地方都可以管理,所以你有多个APP里只要在这里进行设置添加就可以了.

运行工程写入一个密码 1234567890 到keychain里

点击删除与清空后可清除相关内容  点击读取来检查是否删除成功!如果运行出错如下图:

这是因为你的在keychain groups里填写其它的APP bundle ID格式有误  或者 开发者ID填错了其它APP怎么使用keychain里面的数据:首先创建一个工程 getKeyChain 为 :bundle ID为之前工程 keychain Groups 里的添加的当然开发者ID还是同一个

在新工程使用SFHFKeychainUtils 读取和删除 keychain 里面数据

self.userName = @"[email protected]";

self.serviceName = @"space.kylin.www";

_label.text = [SFHFKeychainUtils getPasswordForUsername:self.userName andServiceName:self.serviceName error:nil];

这里的serviceName ,userName 要与之前保存是一致的如果要删除可执行[SFHFKeychainUtils deleteItemForUsername:self.userName andServiceName:self.serviceName error:nil];读取结果:

新浪微博 @火柴大男人

代码下载地址: keychain  最新更新代码 兼容 xcode 7打开工程

链接:https://www.jianshu.com/p/6bc772bdeece

來源:简书

简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

原文地址:https://www.cnblogs.com/sundaysgarden/p/10318734.html

时间: 2024-11-13 16:15:53

iOS数据存储-钥匙串存储的相关文章

iOS数据持久化存储

本文中的代码托管在github上:https://github.com/WindyShade/DataSaveMethods 相对复杂的App仅靠内存的数据肯定无法满足,数据写磁盘作持久化存储是几乎每个客户端软件都需要做的.简单如"是否第一次打开"的BOOL值,大到游戏的进度和状态等数据,都需要进行本地持久化存储.这些数据的存储本质上就是写磁盘存文件,原始一点可以用iOS本身支持有NSFileManager这样的API,或者干脆C语言fwrite/fread,Cocoa Touch本身

iOS数据存储的几种方式

iOS的数据存储是iOS应用开发的重要知识点: 关于这方面知识,网上有很多介绍,但对于代码层次的使用方式并未有系统全面介绍.此文章针对iOS稍熟悉的童鞋,需要对CoreData的原理有一定的了解.目前存储方式大概有以下几种: NSKeyedArchiver  适用简单数据加密 NSUserDefaults  适用配置参数 Write  文件操作,同NSKeyedArchiver SQLite3  操作较复杂,不建议使用. CoreData  取代SQLite3,但要遵循NSManagedObje

IOS开发中关于数据的本地化存储

对于IOS开发者而言, 项目中数据的本地化存储,最难的一点,莫过于SQL语句的编写,除此之外, 其实也没什么难度, 当然在创建数据库之前,我们必须要做的是对数据进行分析, 然后对FMDB进行简单的封装: 代码如下: #import "SQLiteManger.h" #import "FMDB.h" @interface SQLiteManger () @end @implementation SQLiteManger /// 创建一个单例单例 +(instancet

iOS数据存储之CoreData

iOS中大量数据的储存一个是SqLite,另一个就是CoreData,CoreData允许程序员以面向对象的思维方式的方法去操作面向表的数据库 做过Java开发的对这个应该很熟悉,Java中的Hibernate跟CoreData就很相似 CoreData应该怎样使用呢? 第一步,新建工程后导入CoreData框架 第二部,创建CoreData的数据模型创建步骤如下 然后给你的model起个名字,创建完成后你会看到一个这个文件(相当于数据库文件) 点击这个文件,然后看下图 点击图中1,新建实体(类

IOS数据存储 —— 2 存储方式

IOS数据存储方式 iOS开发常用数据存储方式有:plist.偏好设置 NSUserDefaults.对象归档 NSKeyedArchiver.SQLite3和Core Data 1. plist文件 存储 plist文件通常用于储存用户设置,利用xml属性列表归档NSDictionary.NSArray.NSNumber等类型数据 在使用plist进行数据存储和读取,只适用于系统自带的一些常用类型才能用 注意:plist不能存储自定义对象 2. 偏好设置 NSUserDefaults 偏好设置

IOS数据本地存储的四种方式--

注:借鉴于:http://blog.csdn.net/jianjianyuer/article/details/8556024 在IOS开发过程中,不管是做什么应用,都会碰到数据保存问题.将数据保存到本地,能够让程序更加流畅,不会出现让人厌恶的菊花状,使得用户的体验更好.下面是介绍数据保存的方式 第一.NSKeyedArchiver:采用归档的形式来保存数据.(归档——解档)———大量数据和频繁读写不合适使用 1.归档器的作用是将任意的对象集合转换为字节流.这听起来像是NSPropertyLis

iOS数据存储之SqLite3

iOS中数据存储的方式有很多中,当数据量较大的时候偏好设置,归档和plist就无法满足需求了 这时候就需要用SqLite或者CoreData来存储数据 下面就来介绍一下如何使用SqLite存储数据 要使用Sqlite必须引入libSqlite3.dylib库 要使用首先要有一个handle句柄(handle句柄,在C语言中,通常把用于控制某类东西的叫做句柄,实际上是一个指针.) // 数据库句柄 sqlite3 *_db; SqLite存储数据时也是存在一个文件中的,只不过这个文件格式是定制的,

iOS数据持久化之二——归档与设计可存储化的数据模型基类

iOS数据持久化之二--归档与设计可存储化的数据模型基类 一.引言 在上一篇博客中,我们介绍了用plist文件进行数据持久化的方法.虽然简单易用,但随着开发的深入,你会发现,这种方式还是有很大的局限性.试想,如果我们可以将用户的登录返回信息模型,游戏中角色的属性信息模型进行直接的持久化存取,那是不是非常爽的事,幸运的是,我们可以通过归档,来设计一个这样的数据模型. 二.先来精通归档吧 归档也是iOS提供给开发者的一种数据存储的方式,事实上,几乎所有的数据类型都可以通过归档来进行存取.其存储与读取

iOS数据存储类型 及 堆(heap)和栈(stack)

iOS数据存储类型 及 堆(heap)和栈(stack) 一般认为在c中分为这几个存储区: 1栈 --  由编译器自动分配释放. 2堆 --  一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收. 3全局区(静态存储区)-- 全局变量和静态变量的存储是放在一块区域 ,程序退出后自动释放 .全局区又分为全局初始化区和全局未初始化区.初始化的全局变量和静态变量存放在全局初始化区,未初始化的全局变量和未初始化的静态变量存放在相邻的另一块区域. 4常量区-- 专门放数字/字符常量的地方, 程