【发布时间】:2016-08-04 15:33:10
【问题描述】:
目标
我需要以安全方式将客户端身份存储在 OS X 应用程序上,这样只有我的应用程序才能访问它。没有提示请求权限。
问题
当我尝试存储客户身份时,问题立即出现。 这是代码示例(到目前为止我绑定了什么):
- (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
…
}
我不断收到代码 -25299 和工具说明问题:
$ security error -25299
Error: 0xFFFF9D2D -25299 The specified item already exists in the keychain.
因此它尝试覆盖全局客户端身份(我从未成功为此应用程序编写客户端身份,因此不应该发生这种冲突),我不知道该怎么做。 它必须是私有的,只有这个应用程序。
我验证了相应加载代码会发生什么。它加载了我的开发者身份,我不希望这样。
- (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;
}
注意事项
我需要为 iOS 使用相同的代码,但这里应该没问题,因为默认情况下 iOS 钥匙串不会在应用程序之间共享。
【问题讨论】:
-
好吧,看看错误信息。阅读。这应该很明显。您不能添加已存在的项目。有 SecItemUpdate。
-
再读一遍。我需要特定于应用程序的钥匙链。我从来没有添加过这个钥匙链。这是我第一次使用它。此外,当我更改 kSecAttrApplicationTag 的值时,它会给出相同的结果。我不想覆盖全局客户端身份,我需要仅由我的应用程序使用的客户端身份。单独条目。
标签: objective-c macos security keychain