没有合适的资源?快使用搜索试试~ 我知道了~
详解iOS使用Keychain中的kSecClassGenericPassword存储数据
0 下载量 13 浏览量
2021-01-20
09:56:01
上传
评论
收藏 163KB PDF 举报
温馨提示
试读
19页
iOS设备中的Keychain是一个安全的存储容器,可以用来为不同应用保存敏感信息比如用户名,密码,网络密码,认证令牌。苹果自己用keychain来保存Wi-Fi网络密码,VPN凭证等等。它是一个sqlite数据库,位于/private/var/Keychains/keychain-2.db,其保存的所有数据都是加密过的。模拟器下keychain文件路径:~/Library/Application Support/iPhone Simulator/4.3/Library/Keychains keychain里保存的信息不会因App被删除而丢失,在用户重新安装App后依然有效,数据还在。 关于备
资源详情
资源评论
资源推荐
详解详解iOS使用使用Keychain中的中的kSecClassGenericPassword存储数据存储数据
iOS设备中的Keychain是一个安全的存储容器,可以用来为不同应用保存敏感信息比如用户名,密码,网络密码,认证令牌。苹果自己用keychain来保存
Wi-Fi网络密码,VPN凭证等等。它是一个sqlite数据库,位于/private/var/Keychains/keychain-2.db,其保存的所有数据都是加密过的。模拟器下keychain
文件路径:~/Library/Application Support/iPhone Simulator/4.3/Library/Keychains
keychain里保存的信息不会因App被删除而丢失,在用户重新安装App后依然有效,数据还在。
关于备份,只会备份数据,到那时不会备份设备的密钥,换句话说,即使拿到数据,也没有办法解密里面的内容。
比较复杂的数据,使用苹果官方发布的KeychainItemWrapper或者SFHFKeychainUtils会很方便。如果是比较简单的,就不用苹果提供的类了,自己写个
简单的类来实现就好了。
两种方法都需要在”Build Phases“中导入库”Security.framework”
一、自己封装的类一、自己封装的类
((1)实现代码(思路是将数据封装进)实现代码(思路是将数据封装进NSDictionary,通过,通过NSKeyedArchiver归档后保存)归档后保存)
a)MyKeychain.h
//
// MyKeychainh
// UUIDdemo
//
// Created by 555chy on 6/10/
// Copyright © 2016 555chy All rights reserved
//
#import <Foundation/Foundationh>
#import <Security/Securityh>
@interface MyKeychain : NSObject
+ (BOOL)save:(NSString*)service data:(id)data;
+ (id)load:(NSString*)service;
+ (void)delete:(NSString*)service;
@end
b)MyKeychainm
//
// MyKeychainm
// UUIDdemo
//
// Created by 555chy on 6/10/
// Copyright © 2016 555chy All rights reserved
//
#import "MyKeychainh"
@implementation MyKeychain
+ (NSMutableDictionary*) getKeychainQuery: (NSString*)service {
return [NSMutableDictionary dictionaryWithObjectsAndKeys:
(id)kSecClassGenericPassword, (id)kSecClass,
service, (id)kSecAttrService,
service, (id)kSecAttrAccount,
(id)kSecAttrAccessibleAfterFirstUnlock, (id)kSecAttrAccessible,
nil nil];
}
+ (BOOL) save:(NSString*)service data:(id)data {
NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
SecItemDelete((CFDictionaryRef)keychainQuery);
[keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(id)kSecValueData];
return SecItemAdd((CFDictionaryRef)keychainQuery, NULL) == noErr;
}
+ (id) load:(NSString*)service {
id ret = NULL;
NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
[keychainQuery setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
[keychainQuery setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];
NSData *keyData = NULL;
if(SecItemCopyMatching((CFDictionaryRef)keychainQuery, (CFTypeRef*)(void*)&keyData) == noErr) {
@try {
ret = [NSKeyedUnarchiver unarchiveObjectWithData:keyData];
}
@catch (NSException *exception) {
NSLog(@"Unarchive of %@ failed: %@", service, exception);
}
@finally {
}
}
return ret;
}
+ (void) delete:(NSString*)service {
NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
SecItemDelete((CFDictionaryRef)keychainQuery);
}
@end
c)ViewController.m
//
// ViewControllerm
// UUIDdemo
//
// Created by 555chy on 6/10/
// Copyright © 2016 555chy All rights reserved
//
#import "ViewControllerh"
#import "MyKeychainh"
@interface ViewController ()
@end
@implementation ViewController
NSString *KEY_PACKAGE_NAME = @"comchyuuiddemouuid";
NSString *KEY_UUID = @"uuid";
-(void) saveIdfv {
NSString *idfv = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
NSLog(@"get from UIDevice, idfv is %@", idfv);
NSMutableDictionary *dataDict = [NSMutableDictionary dictionary];
[dataDict setObject:idfv forKey:KEY_UUID];
BOOL ret = [MyKeychain save:KEY_PACKAGE_NAME data:dataDict];
NSLog(@"save %@ %@", idfv, ret?@"succ":@"fail");
}
-(void) reloadIdfv {
NSMutableDictionary *loadData = [MyKeychain load:KEY_PACKAGE_NAME];
NSString *loadIdfv = [loadData objectForKey:KEY_UUID];
if(loadIdfv) {
NSLog(@"load idfv is %@", loadIdfv);
} else {
NSLog(@"load idfv, but it not exist");
}
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib
[self reloadIdfv];
[self saveIdfv];
[self reloadIdfv];
[MyKeychain delete:KEY_PACKAGE_NAME];
NSLog(@"delete idfv from keychain");
[self reloadIdfv];
[self saveIdfv];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated
}
@end
(2)运行结果
第一次运行
第二次运行
在模拟器上每次运行实际上都是卸载前一个APP,然后再安装新的APP。而保存在keychain中的IDFV标识符依然还在。
((3)基本语法)基本语法
SecItemAdd 增
SecItemUpdate 改
SecItemDelete 删
SecItemCopyMatching 查
(4)SecItem.h(变量的介绍基本都在头文件中了,看下头文件中的注释就能明白其中的含义)
/*
* Copyright (c) 2006-2014 Apple Inc All Rights Reserved
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 0 (the 'License') You may not use this file except in
* compliance with the License Please obtain a copy of the License at
* http://wwwopensourceapplecom/apsl/ and read it before using this
* file
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT
* Please see the License for the specific language governing rights and
* limitations under the License
*
* @APPLE_LICENSE_HEADER_END@
*/
/*!
@header SecItem
SecItem defines CoreFoundation-based constants and functions for
access to Security items (certificates, keys, identities, and
passwords)
*/
#ifndef _SECURITY_SECITEM_H_
#define _SECURITY_SECITEM_H_
#include <Security/SecBaseh>
#include <CoreFoundation/CFArrayh>
#include <CoreFoundation/CFDictionaryh>
__BEGIN_DECLS
CF_ASSUME_NONNULL_BEGIN
CF_IMPLICIT_BRIDGING_ENABLED
/*!
@enum Class Key Constant
@discussion Predefined key constant used to get or set item class values in
a dictionary Its value is one of the constants defined in the Value
Constants for kSecClass
@constant kSecClass Specifies a dictionary key whose value is the item's
class code You use this key to get or set a value of type CFTypeRef
that contains the item class code
*/
extern const CFStringRef kSecClass
__OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0);
/*!
@enum Class Value Constants
@discussion Predefined item class constants used to get or set values in
a dictionary The kSecClass constant is the key and its value is one
of the constants defined here
@constant kSecClassGenericPassword Specifies generic password items
@constant kSecClassInternetPassword Specifies Internet password items
@constant kSecClassCertificate Specifies certificate items
@constant kSecClassKey Specifies key items
@constant kSecClassIdentity Specifies identity items
*/
extern const CFStringRef kSecClassGenericPassword
__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0);
extern const CFStringRef kSecClassInternetPassword
__OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0);
extern const CFStringRef kSecClassCertificate
剩余18页未读,继续阅读
weixin_38726007
- 粉丝: 6
- 资源: 930
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0