且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何使用Keychain保存密码,如GenericKeychain示例代码

更新时间:2023-12-03 19:51:46

您可以使用安全框架



#import< Security / Security.h>



要保存用户名和密码服务器:

   - (void)saveUsername:(NSString *)user withPassword:(NSString *)pass forServer: (NSString *)server {

//创建搜索参数的字典
NSDictionary * dict = [NSDictionary dictionaryWithObjectsAndKeys:(__ bridge id)(kSecClassInternetPassword),kSecClass,服务器,kSecAttrServer,kCFBooleanTrue,kSecReturnAttributes ,nil];

//从keychain中删除任何旧值
OSStatus err = SecItemDelete((__ bridge CFDictionaryRef)dict);

//创建参数字典添加
NSData * passwordData = [pass dataUsingEncoding:NSUTF8StringEncoding];
dict = [NSDictionary dictionaryWithObjectsAndKeys:(__ bridge id)(kSecClassInternetPassword),kSecClass,server,kSecAttrServer,passwordData,kSecValueData,user,kSecAttrAccount,nil];

//尝试保存到keychain
err = SecItemAdd((__ bridge CFDictionaryRef)dict,NULL);

}

要删除: p>

   - (void)removeAllCredentialsForServer:(NSString *)server {

//创建搜索参数字典
NSDictionary * dict = [NSDictionary dictionaryWithObjectsAndKeys:(__ bridge id)(kSecClassInternetPassword),kSecClass,server,kSecAttrServer,kCFBooleanTrue,kSecReturnAttributes,kCFBooleanTrue,kSecReturnData,nil];

//从keychain中删除任何旧值
OSStatus err = SecItemDelete((__ bridge CFDictionaryRef)dict);

}

要阅读: p>

   - (void)getCredentialsForServer:(NSString *)server {

//创建搜索参数字典
NSDictionary * dict = [NSDictionary dictionaryWithObjectsAndKeys:(__ bridge id)(kSecClassInternetPassword),kSecClass,server,kSecAttrServer,kCFBooleanTrue,kSecReturnAttributes,kCFBooleanTrue,kSecReturnData,nil];

//在keychain中查找服务器
NSDictionary * found = nil;
CFDictionaryRef foundCF;
OSStatus err = SecItemCopyMatching((__ bridge CFDictionaryRef)dict,(CFTypeRef *)& foundCF);

//检查是否找到
found =(__bridge NSDictionary *)(foundCF);
if(!found)
return;

//找到
NSString * user =(NSString *)[found objectForKey:(__ bridge id)(kSecAttrAccount)];
NSString * pass = [[NSString alloc] initWithData:[found objectForKey:(__ bridge id)(kSecValueData)] encoding:NSUTF8StringEncoding];

}


I want to save user's id and password in App.

What is recommendable encryption way when I save id and password.

I'm finding more safe way from Jailbreak or Hacker.

How about GenericKeychain sample code ?

http://developer.apple.com/library/ios/#samplecode/GenericKeychain/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007797

I can't have confidence about safe how to use Keychain like GenericKeychain sample code.

Please tell me some advices. Thank you ^^*

You can use the Security framework

#import <Security/Security.h>

To save a username and password for a server:

-(void) saveUsername:(NSString*)user withPassword:(NSString*)pass forServer:(NSString*)server {

    // Create dictionary of search parameters
    NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:(__bridge id)(kSecClassInternetPassword),  kSecClass, server, kSecAttrServer, kCFBooleanTrue, kSecReturnAttributes, nil];

    // Remove any old values from the keychain
    OSStatus err = SecItemDelete((__bridge CFDictionaryRef) dict);

    // Create dictionary of parameters to add
    NSData* passwordData = [pass dataUsingEncoding:NSUTF8StringEncoding];
    dict = [NSDictionary dictionaryWithObjectsAndKeys:(__bridge id)(kSecClassInternetPassword), kSecClass, server, kSecAttrServer, passwordData, kSecValueData, user, kSecAttrAccount, nil];

    // Try to save to keychain
    err = SecItemAdd((__bridge CFDictionaryRef) dict, NULL);

}

To remove:

-(void) removeAllCredentialsForServer:(NSString*)server {

    // Create dictionary of search parameters
    NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:(__bridge id)(kSecClassInternetPassword),  kSecClass, server, kSecAttrServer, kCFBooleanTrue, kSecReturnAttributes, kCFBooleanTrue, kSecReturnData, nil];

    // Remove any old values from the keychain
    OSStatus err = SecItemDelete((__bridge CFDictionaryRef) dict);

}

To read:

-(void) getCredentialsForServer:(NSString*)server {

    // Create dictionary of search parameters
    NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:(__bridge id)(kSecClassInternetPassword),  kSecClass, server, kSecAttrServer, kCFBooleanTrue, kSecReturnAttributes, kCFBooleanTrue, kSecReturnData, nil];

    // Look up server in the keychain
    NSDictionary* found = nil;
    CFDictionaryRef foundCF;
    OSStatus err = SecItemCopyMatching((__bridge CFDictionaryRef) dict, (CFTypeRef*)&foundCF);

    // Check if found
    found = (__bridge NSDictionary*)(foundCF);
    if (!found) 
        return;

    // Found
    NSString* user = (NSString*) [found objectForKey:(__bridge id)(kSecAttrAccount)];
    NSString* pass = [[NSString alloc] initWithData:[found objectForKey:(__bridge id)(kSecValueData)] encoding:NSUTF8StringEncoding];

}