I can't get the KeychainItemWrapper (Apple example) to work. I've added the KeychainItemWrapper files to my project and when running it on the phone, an exception is thrown by SecItemAdd, saying that one or more parameters were not valid (result code -50). The code triggering the SecItemAdd follows:
KeychainItemWrapper* wrapper = [[KeychainItemWrapper alloc] initWithIdentifier:#"something" accessGroup:nil];
[wrapper setObject:#"this is my password" forKey:#"password"];
NSLog(#"Password: %#", [wrapper objectForKey:#"password"]);
What is wrong?
The code can be found at http://developer.apple.com/iphone/library/samplecode/GenericKeychain/index.html
I ran into this same issue. You can't put arbitrary keys in the dictionary, you need to use well-defined keys that the SecItemAdd understands.
Try this:
KeychainItemWrapper *wrapper = [[KeychainItemWrapper alloc] initWithIdentifier:#"password" accessGroup:nil];
[wrapper setObject:#"this is my password" forKey:(id)kSecValueData];
NSLog(#"password: [%#]", [wrapper objectForKey:(id)kSecValueData]);
[wrapper release];
Related
I use a Multi View, tabbed app. From the FirstViewController, I use PresentViewController to display LoginViewController.
On LoginViewController, I'm using Keychain to save a username and a password when a user logs in on my app.
KeychainItemWrapper *keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:#"LoginInfos" accessGroup:nil];
[keychainItem setObject:_password forKey:(__bridge id)(kSecValueData)];
[keychainItem setObject:_pseudo forKey:(__bridge id)(kSecAttrAccount)];
Now, I'd like to be able to check on FirstViewController if something is set in the keychain, and if so, obviously NOT display LoginViewController. But when I try to access the keychain from FirstViewController, even after doing #import 'KeychainItemWrapper.h', I get an error saying I'm using an undeclared identifier 'keychainItem'.
NSString *mdp = [keychainItem objectForKey:(__bridge id)(kSecValueData)];
NSString *username = [keychainItem objectForKey:(__bridge id)(kSecAttrAccount)];
How can I access the info stored in the Keychain from another view? And is there a better solution (for eg, a global variable?) to check if a user is logged in?
It sounds like you just need to initialize an instance of KeychainItemWrapper in your FirstViewController... Just do:
KeychainItemWrapper *keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:#"LoginInfos" accessGroup:nil];
again before you try retrieving values from it.
I used KeychainItemWrapper for keychain storage.Everything is working fine when i use the forkey:(__bridge id)kSecAttrAccount.But when i use forKey:(__bridge id)(kSecValueData)] app is crashing showing this message in console *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Couldn't add the Keychain Item.'
- (IBAction)saveOne:(id)sender
{
// save edits
keychainItemWrapper1 = [[KeychainItemWrapper alloc] initWithIdentifier:#"one" accessGroup:nil];
[keychainItemWrapper1 setObject:[userOne text] forKey:(__bridge id)(kSecValueData)];
keychainItemWrapper2 = [[KeychainItemWrapper alloc] initWithIdentifier:#"two" accessGroup:nil];
[keychainItemWrapper2 setObject:[userTwo text] forKey:(__bridge id)kSecValueData];
keychainItemWrapper3 = [[KeychainItemWrapper alloc] initWithIdentifier:#"three" accessGroup:nil];
[keychainItemWrapper3 setObject:[userThree text] forKey:(__bridge id)kSecValueData];
}
-(IBAction)reset:(id)sender{
keychainItemWrapper1 = [[KeychainItemWrapper alloc] initWithIdentifier:#"one" accessGroup:nil];
[keychainItemWrapper1 resetKeychainItem];
keychainItemWrapper2 = [[KeychainItemWrapper alloc] initWithIdentifier:#"two" accessGroup:nil];
[keychainItemWrapper2 resetKeychainItem];
keychainItemWrapper3 = [[KeychainItemWrapper alloc] initWithIdentifier:#"three" accessGroup:nil];
[keychainItemWrapper3 resetKeychainItem];
}
can anyone please help me with this.
Thanks in advance.
You may need to look in your - (NSMutableDictionary *)dictionaryToSecItemFormat:(NSDictionary *)dictionaryToConvert method within your KeychainItemWrapper class. Specifically look at your NSMutableDictionary that you are using to write to your keychain. Have you set the key as kSecValueData for the dictionary that you use within the function SecItemAdd or SecItemUpdate? If not, that may be where the problem lies.
I write very secure application (for Bank) and I keep the private key in the Keychain.
I keep the Private key using the following code:
+(void)savePrivatekey:(NSString *)Key
{
KeychainItemWrapper *keychain = [[KeychainItemWrapper alloc] initWithIdentifier:#"pKey" accessGroup:nil];
[keychain setObject:Key forKey:(id)kSecValueData];
[keychain release];
}
and for get the private key using the following code:
+(NSString *)privateKey
{
KeychainItemWrapper *keychain = [[KeychainItemWrapper alloc] initWithIdentifier:#"pKey"accessGroup:nil];
NSString *privateKey = [keychain objectForKey:(id)kSecValueData];
[keychain release];
return privateKey;
}
i don't save the private key in local variable from security reasons.
because every call to server I need the private key i call to to function
"GetPrivateKey" a lot of times.
Maybe that's why sometimes i get from the keychain empty string.
i can't think of why this might happen.
I noticed that in most cases this happens when the application return from background but no only...
thanks...
I opened ticket at Apple's engineers and they responded to me:
Are you setting the kSecAttrAccessible attribute when you create the keychain item initially?
I always create the same shape keychain:
KeychainItemWrapper * keychain = [[KeychainItemWrapper alloc] initWithIdentifier: # "pKey" accessGroup: nil];
Does anyone know what their intent?
thanks...
I answered my own question a while back regarding this. I'm not sure if this is your exact problem as your code seems to look/work fine. So regarding your keychain access, I'm guessing it is a bit different. This may or may not help, but might steer you in the right direction.
iOS KeyChain not retrieving values from background
If your class is using ARC the following works for me every time.
KeychainItemWrapper *testKeychain = [[KeychainItemWrapper alloc] initWithIdentifier:#"AppUniqueID" accessGroup:nil];
NSString *privateKey = [testKeychain objectForKey:(__bridge id)(kSecValueData)];
NSLog(#"Private Key: %# \n", privateKey);
I am using Keychainwrapper class downloaded from Apple documentation for storing login information like password. In my apps when user click on sign in button, I am storing in key chain like below...
KeychainItemWrapper *keychainItem = [[KeychainItemWrapper alloc]
initWithIdentifier : #"vmo_login" accessGroup:nil];
[keychainItem setObject:email_id.text forKey:(__bridge NSString*)kSecAttrAccount];
[keychainItem setObject:password.text forKey:(__bridge NSString*)kSecValueData];
And if user click on sign out I am exiting application with exit(1). Once application is launched again, I am reading from keychain like below..
NSString *loc_email1 = [keychainItem objectForKey:(__bridge NSString*)kSecAttrAccount];
NSString *loc_pwd1 = [keychainItem objectForKey:(__bridge NSString*)kSecValueData];
I have not got what I have stored below, it returns NULL. Any Idea?.
thanks.
I have found the problem..
KeychainItemWrapper *keychainItem = [[KeychainItemWrapper alloc]
initWithIdentifier : #"<need to give same as when we write>" accessGroup:nil];
Working fine now.
I'm using the following code within XCode, building for iOS with ARC enabled. Why are these errors appearing?
Here's my code:
KeychainItemWrapper *keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:#"Test" accessGroup:nil];
[keychainItem setObject:#"Test" forKey:kSecAttrService];
[keychainItem setObject:password.text forKey:kSecValueData];
[keychainItem setObject:username.text forKey:kSecAttrAccount];
You're getting this because kSecAttrAccount and such aren't Obj-C types. Just place a (__bridge id) before each like
[keychainItem setObject:password.text forKey:(__bridge id)kSecValueData];