Simple iPhone Keychain Access
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 whenev
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.
The only problem is that accessing the keychain services is complicated and even the GenericKeychain example code is hard to follow. I hate to include cut and pasted code into my application, especially when I do not understand it. Instead I have gone back to basics to build up a simple iPhone keychain access example that does just what I want and not much more.
In fact all I really want to be able to do is securely store a password string for my application and be able to retrieve it a later date.
Getting Started
A couple of housekeeping items to get started:
- Add the “Security.framework” framework to your iPhone application
- Include the header file
Note that the security framework is a good old fashioned C framework so no Objective-C style methods calls. Also it will only work on the device not in in the iPhone Simulator.
The Basic Search Dictionary
All of the calls to the keychain services make use of a dictionary to define the attributes of the keychain item you want to find, create, update or delete. So the first thing we will do is define a function to allocate and construct this dictionary for us:
<code>static NSString *serviceName = @"com.mycompany.myAppServiceName"; - (NSMutableDictionary *)newSearchDictionary:(NSString *)identifier { NSMutableDictionary *searchDictionary = [[NSMutableDictionary alloc] init]; [searchDictionary setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass]; NSData *encodedIdentifier = [identifier dataUsingEncoding:NSUTF8StringEncoding]; [searchDictionary setObject:encodedIdentifier forKey:(id)kSecAttrGeneric]; [searchDictionary setObject:encodedIdentifier forKey:(id)kSecAttrAccount]; [searchDictionary setObject:serviceName forKey:(id)kSecAttrService]; return searchDictionary; } </code>
The dictionary contains three items. The first with key kSecClass defines the class of the keychain item we will be dealing with. I want to store a password in the keychain so I use the value kSecClassGenericPassword for the value.
The second item in the dictionary with key kSecAttrGeneric is what we will use to identify the keychain item. It can be any value we choose such as “Password” or “LicenseKey”, etc. To be clear this is not the actual value of the password just a label we will attach to this keychain item so we can find it later. In theory our application could store a number of passwords in the keychain so we need to have a way to identify this particular one from the others. The identifier has to be encoded before being added to the dictionary
The combination of the final two attributes kSecAttrAccount and kSecAttrService should be set to something unique for this keychain. In this example I set the service name to a static string and reuse the identifier as the account name.
You can use multiple attributes for a given class of item. Some of the other attributes that we could also use for the kSecClassGenericPassword item include an account name, description, etc. However by using just a single attribute we can simplify the rest of the code.
Searching the keychain
To find out if our password already exists in the keychain (and what the value of the password is) we use the SecItemCopyMatching function. But first we add a couple of extra items to our basic search dictionary:
<code>- (NSData *)searchKeychainCopyMatching:(NSString *)identifier { NSMutableDictionary *searchDictionary = [self newSearchDictionary:identifier]; // Add search attributes [searchDictionary setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit]; // Add search return types [searchDictionary setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData]; NSData *result = nil; OSStatus status = SecItemCopyMatching((CFDictionaryRef)searchDictionary, (CFTypeRef *)&result); [searchDictionary release]; return result; } </code>
The first attribute we add to the dictionary is to limit the number of search results that get returned. We are looking for a single entry so we set the attribute kSecMatchLimit to kSecMatchLimitOne.
The next attribute determines how the result is returned. Since in our simple case we are expecting only a single attribute to be returned (the password) we can set the attribute kSecReturnData to kCFBooleanTrue. This means we will get an NSData reference back that we can access directly.
If we were storing and searching for a keychain item with multiple attributes (for example if we were storing an account name and password in the same keychain item) we would need to add the attribute kSecReturnAttributes and the result would be a dictionary of attributes.
Now with the search dictionary set up we call the SecItemCopyMatching function and if our item exists in the keychain the value of the password is returned to in the NSData block. To get the actual decoded string you could do something like:
<code> NSData *passwordData = [self searchKeychainCopyMatching:@"Password"]; if (passwordData) { NSString *password = [[NSString alloc] initWithData:passwordData encoding:NSUTF8StringEncoding]; [passwordData release]; } </code>
Creating an item in the keychain
Adding an item is almost the same as the previous examples except that we need to set the value of the password we want to store.
<code>- (BOOL)createKeychainValue:(NSString *)password forIdentifier:(NSString *)identifier { NSMutableDictionary *dictionary = [self newSearchDictionary:identifier]; NSData *passwordData = [password dataUsingEncoding:NSUTF8StringEncoding]; [dictionary setObject:passwordData forKey:(id)kSecValueData]; OSStatus status = SecItemAdd((CFDictionaryRef)dictionary, NULL); [dictionary release]; if (status == errSecSuccess) { return YES; } return NO; } </code>
To set the value of the password we add the attribute kSecValueData to our search dictionary making sure we encode the string and then call SecItemAdd passing the dictionary as the first argument. If the item already exists in the keychain this will fail.
Updating a keychain item
Updating a keychain is similar to adding an item except that a separate dictionary is used to contain the attributes to be updated. Since in our case we are only updating a single attribute (the password) this is easy:
<code>- (BOOL)updateKeychainValue:(NSString *)password forIdentifier:(NSString *)identifier { NSMutableDictionary *searchDictionary = [self newSearchDictionary:identifier]; NSMutableDictionary *updateDictionary = [[NSMutableDictionary alloc] init]; NSData *passwordData = [password dataUsingEncoding:NSUTF8StringEncoding]; [updateDictionary setObject:passwordData forKey:(id)kSecValueData]; OSStatus status = SecItemUpdate((CFDictionaryRef)searchDictionary, (CFDictionaryRef)updateDictionary); [searchDictionary release]; [updateDictionary release]; if (status == errSecSuccess) { return YES; } return NO; } </code>
Deleting an item from the keychain
The final (and easiest) operation is to delete an item from the keychain using the SecItemDelete function and our usual search dictionary:
<code>- (void)deleteKeychainValue:(NSString *)identifier { NSMutableDictionary *searchDictionary = [self newSearchDictionary:identifier]; SecItemDelete((CFDictionaryRef)searchDictionary); [searchDictionary release]; } </code>

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

苹果iPhone17或将迎来重大升级,以应对国内华为、小米等强劲竞争对手的冲击。据数码博主@数码闲聊站爆料,iPhone17标准版有望首次搭载高刷新率屏幕,显着提升用户体验。此举标志着苹果历经五年,终于将高刷新率技术下放至标准版机型。目前,iPhone16作为6000元价位段唯一一款配备60Hz屏幕的旗舰手机,显得有些落后。虽然iPhone17标准版将拥有高刷新率屏幕,但与Pro版相比仍存在差异,例如边框设计仍未达到Pro版的超窄边框效果。更值得关注的是,iPhone17Pro系列将采用全新、更

如何在 Apache 中配置 Zend?在 Apache Web 服务器中配置 Zend Framework 的步骤如下:安装 Zend Framework 并解压到 Web 服务器目录中。创建 .htaccess 文件。创建 Zend 应用程序目录并添加 index.php 文件。配置 Zend 应用程序(application.ini)。重新启动 Apache Web 服务器。

本文介绍如何在Debian系统上有效监控Nginx服务器的SSL性能。我们将使用NginxExporter将Nginx状态数据导出到Prometheus,再通过Grafana进行可视化展示。第一步:配置Nginx首先,我们需要在Nginx配置文件中启用stub_status模块来获取Nginx的状态信息。在你的Nginx配置文件(通常位于/etc/nginx/nginx.conf或其包含文件中)中添加以下代码段:location/nginx_status{stub_status

PHPMyAdmin安全防御策略的关键在于:1. 使用最新版PHPMyAdmin及定期更新PHP和MySQL;2. 严格控制访问权限,使用.htaccess或Web服务器访问控制;3. 启用强密码和双因素认证;4. 定期备份数据库;5. 仔细检查配置文件,避免暴露敏感信息;6. 使用Web应用防火墙(WAF);7. 进行安全审计。 这些措施能够有效降低PHPMyAdmin因配置不当、版本过旧或环境安全隐患导致的安全风险,保障数据库安全。

vProcesserazrabotkiveb被固定,мнелостольностьстьс粹馏标д都LeavallySumballanceFriablanceFaumDoptoMatification,Čtookazalovnetakprosto,kakaožidal.posenesko

电商平台SKU和SPU表设计详解本文将探讨电商平台中SKU和SPU的数据库设计问题,特别是如何处理用户自定义销售属...

有效监控和防御恶意网站访问对于Debian系统的Apache服务器至关重要。Apache访问日志是识别此类威胁的关键信息来源。本文将指导您如何分析日志并采取防御措施。识别恶意访问行为Debian系统的Apache访问日志通常位于/var/log/apache2/access.log。您可以通过多种方法分析日志:日志文件位置确认:首先,请确认您的Apache访问日志的准确位置,它可能因系统配置而略有不同。命令行工具分析:使用grep命令搜索特定模式,例如grep"404"

Apache服务器是强大的Web服务器软件,充当浏览器与网站服务器间的桥梁。1. 它处理HTTP请求,根据请求返回网页内容;2. 模块化设计允许扩展功能,例如支持SSL加密和动态网页;3. 配置文件(如虚拟主机配置)需谨慎设置,避免安全漏洞,并需优化性能参数,例如线程数和超时时间,才能构建高性能、安全的Web应用。
