iOS开发之keychain的使用

2024-06-08 10:38
文章标签 使用 开发 ios keychain

本文主要是介绍iOS开发之keychain的使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

什么是keychain?以及keychain的作用。

The keychain is about the only place that an iPhone application can safely store data that will be preserved across a re-installation of the application. Each iPhone application gets its own set of keychain items which are backed up whenever the user backs up the device via iTunes. The backup data is encrypted as part of the backup so that it remains secure even if somebody gets access to the backup data. This makes it very attractive to store sensitive data such as passwords, license keys, etc.

keychain的用法


WQKeyChain.h

#import <Foundation/Foundation.h>@interface WQKeyChain : NSObject
+ (NSMutableDictionary *)getKeychainQuery:(NSString *)service;
+ (void)save:(NSString *)service data:(id)data;
+ (id)load:(NSString *)service;
+ (void)delete:(NSString *)service;@end

WQKeyChain.m

#import "WQKeyChain.h"@implementation WQKeyChain+ (NSMutableDictionary *)getKeychainQuery:(NSString *)service {return [NSMutableDictionary dictionaryWithObjectsAndKeys:(__bridge_transfer id)kSecClassGenericPassword,(__bridge_transfer id)kSecClass,service, (__bridge_transfer id)kSecAttrService,service, (__bridge_transfer id)kSecAttrAccount,(__bridge_transfer id)kSecAttrAccessibleAfterFirstUnlock,(__bridge_transfer id)kSecAttrAccessible,nil];
}+ (void)save:(NSString *)service data:(id)data {//Get search dictionaryNSMutableDictionary *keychainQuery = [self getKeychainQuery:service];//Delete old item before add new itemSecItemDelete((__bridge_retained CFDictionaryRef)keychainQuery);//Add new object to search dictionary(Attention:the data format)[keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(__bridge_transfer id)kSecValueData];//Add item to keychain with the search dictionarySecItemAdd((__bridge_retained CFDictionaryRef)keychainQuery, NULL);
}+ (id)load:(NSString *)service {id ret = nil;NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];//Configure the search setting[keychainQuery setObject:(id)kCFBooleanTrue forKey:(__bridge_transfer id)kSecReturnData];[keychainQuery setObject:(__bridge_transfer id)kSecMatchLimitOne forKey:(__bridge_transfer id)kSecMatchLimit];CFDataRef keyData = NULL;if (SecItemCopyMatching((__bridge_retained CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) {@try {ret = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge_transfer NSData *)keyData];} @catch (NSException *e) {NSLog(@"Unarchive of %@ failed: %@", service, e);} @finally {}}return ret;
}+ (void)delete:(NSString *)service {NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];SecItemDelete((__bridge_retained CFDictionaryRef)keychainQuery);
}@end

WQUserDataManager.h

#import <Foundation/Foundation.h>@interface WQUserDataManager : NSObject/***    @brief    存储密码**    @param     password     密码内容*/
+(void)savePassWord:(NSString *)password;/***    @brief    读取密码**    @return    密码内容*/
+(id)readPassWord;/***    @brief    删除密码数据*/
+(void)deletePassWord;@end

WQUserDataManager.m

#import "WQUserDataManager.h"
#import "WQKeyChain.h"@implementation WQUserDataManagerstatic NSString * const KEY_IN_KEYCHAIN = @"com.my.app.allinfo";
static NSString * const KEY_PASSWORD = @"com.my.app.password";+(void)savePassWord:(NSString *)password
{NSMutableDictionary *usernamepasswordKVPairs = [NSMutableDictionary dictionary];[usernamepasswordKVPairs setObject:password forKey:KEY_PASSWORD];[WQKeyChain save:KEY_IN_KEYCHAIN data:usernamepasswordKVPairs];
}+(id)readPassWord
{NSMutableDictionary *usernamepasswordKVPair = (NSMutableDictionary *)[WQKeyChain load:KEY_IN_KEYCHAIN];return [usernamepasswordKVPair objectForKey:KEY_PASSWORD];
}+(void)deletePassWord
{[WQKeyChain delete:KEY_IN_KEYCHAIN];
}
@end


具体的调用,看什么样的需求了,写到所需的地方就是了。以下为一小例:

if (self.textField.text && self.textField.text.length != 0) {
[WQUserDataManager savePassWord:self.textField.text];
self.label.text = [WQUserDataManager readPassWord];
}else{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"密码不能为空" message:nil delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
}


运行结果:

输入密码,点击“测试按钮”测试。



这篇关于iOS开发之keychain的使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1041952

相关文章

Spring Security基于数据库的ABAC属性权限模型实战开发教程

《SpringSecurity基于数据库的ABAC属性权限模型实战开发教程》:本文主要介绍SpringSecurity基于数据库的ABAC属性权限模型实战开发教程,本文给大家介绍的非常详细,对大... 目录1. 前言2. 权限决策依据RBACABAC综合对比3. 数据库表结构说明4. 实战开始5. MyBA

使用Python自建轻量级的HTTP调试工具

《使用Python自建轻量级的HTTP调试工具》这篇文章主要为大家详细介绍了如何使用Python自建一个轻量级的HTTP调试工具,文中的示例代码讲解详细,感兴趣的小伙伴可以参考一下... 目录一、为什么需要自建工具二、核心功能设计三、技术选型四、分步实现五、进阶优化技巧六、使用示例七、性能对比八、扩展方向建

使用Python实现一键隐藏屏幕并锁定输入

《使用Python实现一键隐藏屏幕并锁定输入》本文主要介绍了使用Python编写一个一键隐藏屏幕并锁定输入的黑科技程序,能够在指定热键触发后立即遮挡屏幕,并禁止一切键盘鼠标输入,这样就再也不用担心自己... 目录1. 概述2. 功能亮点3.代码实现4.使用方法5. 展示效果6. 代码优化与拓展7. 总结1.

使用Python开发一个简单的本地图片服务器

《使用Python开发一个简单的本地图片服务器》本文介绍了如何结合wxPython构建的图形用户界面GUI和Python内建的Web服务器功能,在本地网络中搭建一个私人的,即开即用的网页相册,文中的示... 目录项目目标核心技术栈代码深度解析完整代码工作流程主要功能与优势潜在改进与思考运行结果总结你是否曾经

Linux中的计划任务(crontab)使用方式

《Linux中的计划任务(crontab)使用方式》:本文主要介绍Linux中的计划任务(crontab)使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、前言1、linux的起源与发展2、什么是计划任务(crontab)二、crontab基础1、cro

kotlin中const 和val的区别及使用场景分析

《kotlin中const和val的区别及使用场景分析》在Kotlin中,const和val都是用来声明常量的,但它们的使用场景和功能有所不同,下面给大家介绍kotlin中const和val的区别,... 目录kotlin中const 和val的区别1. val:2. const:二 代码示例1 Java

C++变换迭代器使用方法小结

《C++变换迭代器使用方法小结》本文主要介绍了C++变换迭代器使用方法小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1、源码2、代码解析代码解析:transform_iterator1. transform_iterat

C++中std::distance使用方法示例

《C++中std::distance使用方法示例》std::distance是C++标准库中的一个函数,用于计算两个迭代器之间的距离,本文主要介绍了C++中std::distance使用方法示例,具... 目录语法使用方式解释示例输出:其他说明:总结std::distance&n编程bsp;是 C++ 标准

vue使用docxtemplater导出word

《vue使用docxtemplater导出word》docxtemplater是一种邮件合并工具,以编程方式使用并处理条件、循环,并且可以扩展以插入任何内容,下面我们来看看如何使用docxtempl... 目录docxtemplatervue使用docxtemplater导出word安装常用语法 封装导出方

Linux换行符的使用方法详解

《Linux换行符的使用方法详解》本文介绍了Linux中常用的换行符LF及其在文件中的表示,展示了如何使用sed命令替换换行符,并列举了与换行符处理相关的Linux命令,通过代码讲解的非常详细,需要的... 目录简介检测文件中的换行符使用 cat -A 查看换行符使用 od -c 检查字符换行符格式转换将