Apple keychain store client identity, damit nur meine Anwendung darauf zugreifen kann
Ich muss die Client-Identität in einer OS X-Anwendung auf sichere Weise so speichern, dass nur meine Anwendung darauf zugreifen kann. Keine Aufforderung, nach Berechtigungen zu fragen.
ProbleProblem wurde sofort angezeigt, als ich versuchte, die Client-Identität zu speichern. Hier ist ein Codebeispiel (was ich bisher gebunden habe):
- (BOOL)saveClientIdentity:(SecIdentityRef)clientIdentity error:(NSError**) error
{
NSDictionary *attributes = @{
(__bridge id)kSecAttrAccessible:(__bridge id)kSecAttrAccessibleAlwaysThisDeviceOnly,
(__bridge id)kSecValueRef:(__bridge id)clientIdentity,
(__bridge id)kSecAttrApplicationTag:[kMyKeychainAttrApplicationTag dataUsingEncoding: NSUTF8StringEncoding],
(__bridge id)kSecAttrAccessGroup:kMyKeychainAttrAccessGroup
};
OSStatus status = SecItemAdd((__bridge CFDictionaryRef)attributes, NULL);
// status == -25299
…
}
Ich bekomme ständig Code -25299 und Tool Expalint das Problem:
$ security error -25299
Error: 0xFFFF9D2D -25299 The specified item already exists in the keychain.
So versucht es, die globale Clientidentität zu überschreiben (ich habe nie eine Clientidentität für diese Anwendung geschrieben, daher sollte es keinen solchen Konflikt geben) und ich weiß nicht, was ich tun soll. Es muss nur für diese Anwendung privat sein.
Ich habe überprüft, was für den jeweiligen Ladecode passiert. Es lädt meine Entwickleridentität und ich möchte das nicht.
- (SecIdentityRef)clientIdentity
{
NSDictionary *attributes =
@{
(__bridge id)kSecClass:(__bridge id)kSecClassIdentity,
(__bridge id)kSecAttrAccessible:(__bridge id)kSecAttrAccessibleAlwaysThisDeviceOnly,
(__bridge id)kSecAttrApplicationTag:[kMyKeychainAttrApplicationTag dataUsingEncoding: NSUTF8StringEncoding],
(__bridge id)kSecAttrAccessGroup:kMyKeychainAttrAccessGroup
};
CFTypeRef universalResult = NULL;
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)attributes, &universalResult);
SecIdentityRef result = (SecIdentityRef)universalResult;
if (result)
{
CFAutorelease(result);
}
if (status != noErr)
{
NSLog(@"Failed to load client identity: %@", NSErrorFromStatusErrorCode(status));
}
return result;
}
AnmerkungeIch muss denselben Code für iOS verwenden, aber dies sollte kein Problem sein, da der iOS-Schlüsselbund standardmäßig nicht von Anwendungen gemeinsam genutzt wird.