سؤال

All this happened in my simulator. While practicing using keychain wrappers I've found myself in a strange situation. I was trying to learn how to insert and retrieve data form the keychain, and, in order to do this, I started a new project in which, the only thing I did, was writing in the "(void)viewDidLoad" method of my ViewController a default username, a default password, storing and trying to retrieve them on a second run of my Application.

This should have been a piece of cake but I've found out that my application was crashing. This is the code I used:

- (void)viewDidLoad{

[super viewDidLoad];

//Keychain wrapper definition
KeychainItemWrapper *keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:@"YourAppLogin" accessGroup:nil];

//Getting DATA:
NSLog(@"Retrieving User DATA");
password = [keychainItem objectForKey:(__bridge id)(kSecValueData)];
username = [keychainItem objectForKey:(__bridge id)(kSecAttrAccount)];
NSLog(@"pwd = %@",password);
NSLog(@"user = %@",username);

//Setting DATA:
[keychainItem setObject:@"password you are saving" forKey:(__bridge id)(kSecValueData)];
[keychainItem setObject:@"username you are saving" forKey:(__bridge id)(kSecAttrAccount)];  
}

Xcode was giving me an NSInternalInconsistencyException uncaught. Playing around with the code I realized that the problem occurred only when setting a new password (at the first run of my App or after a reset of the keychain) and, here comes the strange part, only if I set my password before the username. So rewriting the code swapping the

//Setting DATA
[keychainItem setObject:@"username you are saving" forKey:(__bridge id)(kSecAttrAccount)];
[keychainItem setObject:@"password you are saving" forKey:(__bridge id)(kSecValueData)];     
}  

solved my problem. Can anybody explain me why?

Finally I would like to ask if retrieving my password in a second run of my application will result in a encrypted version of it. This because i tried to get my password in 2 ways:

1) I got it right after storing it

//saving DATA
[keychainItem setObject:@"username you are saving" forKey:(__bridge id)(kSecAttrAccount)];
[keychainItem setObject:@"password you are saving" forKey:(__bridge id)(kSecValueData)];

//getting DATA:
username = [keychainItem objectForKey:(__bridge id)(kSecAttrAccount)];
password = [keychainItem objectForKey:(__bridge id)(kSecValueData)];
NSLog(@"\nUser: %@ \nPassword: %@",username,password);  

the result was

User: username you are saving
Password: password you are saving

2)I got my password in a second run putting the setting part under comment

//saving DATA
//[keychainItem setObject:@"username you are saving" forKey:(__bridge id)(kSecAttrAccount)];
//[keychainItem setObject:@"password you are saving" forKey:(__bridge id)(kSecValueData)];

//getting DATA:
username = [keychainItem objectForKey:(__bridge id)(kSecAttrAccount)];
password = [keychainItem objectForKey:(__bridge id)(kSecValueData)];
NSLog(@"\nUser: %@ \nPassword: %@",username,password);  

the result was

User: username you are saving
Password: <70617373 776f7264 20796f75 20617265 20736176 696e67>

So is this a encrypted version of my password or what???

Thank you

هل كانت مفيدة؟

المحلول

I haven't understood why putting in the Keychain the password before the username makes the app crash, but I learned that, in order to get the password back from the keychain you have to store it first in a NSData, you should do so:

NSData *pwd = [keychainItem objectForKey:(__bridge id)(kSecValueData)]; 
password =    [[NSString alloc] initWithData:pwd encoding:NSUTF8StringEncoding];
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top