2008-10-10 6 views

답변

34

코드는 가장 좋은 방법은 애플에서 GenericKeychain 샘플 응용 프로그램을 확인하는 것입니다 하나의 응용 프로그램이 동일한 키 체인 정보에 액세스하는 경우 와일드 카드 AppID (#####. com.prefix. *)를 생성해야합니다.

+1

감사합니다! – maralbjo

5

의 AppID를 생성 할 때 더 원하는 경우 기억 - 당신이 사용할 수있는 키 체인이

44

키 체인 API는 iPhone SDK의 이전 버전 (2.x, 3.x)을 사용할 때 시뮬레이터에서 작업하십시오. 이렇게하면 테스트 할 때 많은 좌절감을 줄일 수 있습니다!

+0

이것은 잠시 동안 수정되었습니다. 그것은 나를 위해 시뮬레이터에서 작동합니다. – bartvdpoel

+0

예, 이제 시뮬레이션에서 작동합니다. 나는 그것이 3.x 릴리스에서 수정되었다고 생각한다. –

8

나는 정말로 Buzz Anderson's Keychain abstraction layer을 좋아하며, 사용 가능한 상태에 이르기까지 열심히 Jens Alfke's MYCrypto을 기다리고 있습니다. 후자는 동일한 코드를 사용하여 Mac OS X 및 iPhone에서 사용하도록 허용하는 유능한 작업을 수행하지만 기능은 키 체인의 일부만 모방합니다.

8

다음은 키/값 쌍을 키 체인에 저장하는 데 사용하는 항목입니다. 프로젝트

#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; 
    } 
} 

그것은 사용자가 응용 프로그램을 삭제하면이/키 값이 삭제되지 것이라는 점을 주목할 필요가에 Security.framework를 추가해야합니다. 사용자가 앱을 삭제했다가 다시 설치하면 키/값에 계속 액세스 할 수 있습니다. 여기

+0

이 코드는 iOS 4.3을 실행하는 시뮬레이터에서 잘 작동했습니다. – AlBeebe

+2

Selector getSecureValueForKey에 버그가 있습니다. 값을 반환하면 이미 릴리스되었습니다. 그것은 "[결과 발표]에 의해 발표됩니다;" –

+0

Objective-C 메서드 대신 C 함수로 수정되었습니다. 필자의 경우,이 기능을 내 응용 프로그램의 모든 객체에서 사용할 수 있도록 만들고 싶습니다. 기능 자체에는 영구 저장 장치 (ivars)가 필요하지 않습니다. 그러나 그렇지 않으면 위대한 발췌문! –

관련 문제