我可以访问iPhone上的钥匙串吗?
这个问题讨论使用crypt()函数在iPhone上encryption数据 。 作为替代scheme,iPhone上是否有钥匙串?如果是,我将使用哪些代码来访问它以存储login细节,然后在应用程序中为我们检索它们?
有一个钥匙串可以使用 – 对于代码来说,最好的办法是查看Apple的GenericKeychain示例应用程序:
通用钥匙链样本
另外要注意的是:使用iPhone SDK的旧版本(2.x,3.x)时,钥匙串API在模拟器中不起作用。 testing时,这可以为您节省很多挫折!
我真的很喜欢Buzz Anderson的Keychain抽象层 ,我急切地等待Jens Alfke的MYCrypto达到可用状态。 后者做了一个允许在Mac OS X和iPhone上使用相同代码的工作,尽pipe它的function仅仅模仿了Keychain的一小部分。
这是我用来存储Keychain中的Key / Value对。 确保将Security.framework添加到您的项目
#import <Security/Security.h> // ------------------------------------------------------------------------- -(NSString *)getSecureValueForKey:(NSString *)key { /* Return a value from the keychain */ // Retrieve a value from the keychain NSDictionary *result; NSArray *keys = [[[NSArray alloc] initWithObjects: (NSString *) kSecClass, kSecAttrAccount, kSecReturnAttributes, nil] autorelease]; NSArray *objects = [[[NSArray alloc] initWithObjects: (NSString *) kSecClassGenericPassword, key, kCFBooleanTrue, nil] autorelease]; NSDictionary *query = [[NSDictionary alloc] initWithObjects: objects forKeys: keys]; // Check if the value was found OSStatus status = SecItemCopyMatching((CFDictionaryRef) query, (CFTypeRef *) &result); [query release]; if (status != noErr) { // Value not found return nil; } else { // Value was found so return it NSString *value = (NSString *) [result objectForKey: (NSString *) kSecAttrGeneric]; return value; } } // ------------------------------------------------------------------------- -(bool)storeSecureValue:(NSString *)value forKey:(NSString *)key { /* Store a value in the keychain */ // Get the existing value for the key NSString *existingValue = [self getSecureValueForKey:key]; // Check if a value already exists for this key OSStatus status; if (existingValue) { // Value already exists, so update it NSArray *keys = [[[NSArray alloc] initWithObjects: (NSString *) kSecClass, kSecAttrAccount, nil] autorelease]; NSArray *objects = [[[NSArray alloc] initWithObjects: (NSString *) kSecClassGenericPassword, key, nil] autorelease]; NSDictionary *query = [[[NSDictionary alloc] initWithObjects: objects forKeys: keys] autorelease]; status = SecItemUpdate((CFDictionaryRef) query, (CFDictionaryRef) [NSDictionary dictionaryWithObject:value forKey: (NSString *) kSecAttrGeneric]); } else { // Value does not exist, so add it NSArray *keys = [[[NSArray alloc] initWithObjects: (NSString *) kSecClass, kSecAttrAccount, kSecAttrGeneric, nil] autorelease]; NSArray *objects = [[[NSArray alloc] initWithObjects: (NSString *) kSecClassGenericPassword, key, value, nil] autorelease]; NSDictionary *query = [[[NSDictionary alloc] initWithObjects: objects forKeys: keys] autorelease]; status = SecItemAdd((CFDictionaryRef) query, NULL); } // Check if the value was stored if (status != noErr) { // Value was not stored return false; } else { // Value was stored return true; } }
值得注意的是,如果用户删除你的应用程序,这些键/值将不会被删除。 如果用户删除您的应用程序,然后重新安装它,键/值仍然可以访问。
还要记住,当生成一个AppID,如果你想多个应用程序访问相同的钥匙串信息,你必须生成一个通配符AppID(#####。com.prefix。*)…
使用GenericKeychain示例的最新版本1.2 Apple提供了一个也在iPhone Simulator上运行的钥匙串包装器。 看看这篇文章的详细信息: http : //dev-metal.blogspot.com/2010/08/howto-use-keychain-in-iphone-sdk-to.html
这是来自Mr.Granoff的一个更好的包装类https://github.com/granoff/Lockbox谢谢;