Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to store manually in ios keychain?

for my app i have to store username/password in a secure way and think its best solution to store in the system keychain. what is the best way to that? do i need mandatory a keychain tool like FDKeychain or is there an easy way to do it without such a Wrapper?

Thx

like image 819
thorb65 Avatar asked Dec 14 '13 19:12

thorb65


1 Answers

you can store values manually in this way (iOS7):

EDIT: Martin R notes that if the key is already in usage SecItemAdd fails. In that case SecItemUpdate has to be called.

NSString *key = @"full_name";
NSString *value = @"My Name";
NSData *valueData = [value dataUsingEncoding:NSUTF8StringEncoding];
NSString *service = [[NSBundle mainBundle] bundleIdentifier];

NSDictionary *secItem = @{
    (__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword,
    (__bridge id)kSecAttrService : service,
    (__bridge id)kSecAttrAccount : key,
    (__bridge id)kSecValueData : valueData,};

CFTypeRef result = NULL;
OSStatus status = SecItemAdd((__bridge CFDictionaryRef)secItem, &result);
if (status == errSecSuccess){ 
    NSLog(@"value saved");
}else{
    NSLog(@"error: %ld", (long)status);
}

and then you can retrieve it like this:

NSString *keyToSearchFor = @"full_name";
NSString *service = [[NSBundle mainBundle] bundleIdentifier];

NSDictionary *query = @{
    (__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword, 
    (__bridge id)kSecAttrService : service,
    (__bridge id)kSecAttrAccount : keyToSearchFor,
    (__bridge id)kSecReturnAttributes : (__bridge id)kCFBooleanTrue, };

CFDictionaryRef valueAttributes = NULL;
OSStatus results = SecItemCopyMatching((__bridge CFDictionaryRef)query,
                                           (CFTypeRef *)&valueAttributes);
NSDictionary *attributes = (__bridge_transfer NSDictionary *)valueAttributes;

if (results == errSecSuccess){
     NSString *key, *accessGroup, *creationDate, *modifiedDate, *service;
     key = attributes[(__bridge id)kSecAttrAccount];
     accessGroup = attributes[(__bridge id)kSecAttrAccessGroup];
     creationDate = attributes[(__bridge id)kSecAttrCreationDate];
     modifiedDate = attributes[(__bridge id)kSecAttrModificationDate];
     service = attributes[(__bridge id)kSecAttrService];
} else {
    NSLog(@"error: %ld", (long)results);
}
like image 126
wmvis Avatar answered Sep 24 '22 19:09

wmvis