我正在创建一个钥匙串,然后我正在添加一个带有预定义可信应用程序列表的项目:
SecKeychainCreate([keychainPath UTF8String], (UInt32)strlen(keychainPass), keychainPass, FALSE, NULL, &someKeychain);
OSStatus someStatus = SecKeychainItemCreateFromContent(kSecGenericPasswordItemClass, &list, len, encryptedPass, someKeychain, accessRef, &someKeychainItem);
当我使用Keychain Access应用程序打开新创建的钥匙串时,我可以在受信任的应用程序列表中看到我的应用程序:
问题是,当我尝试通过其中一个受信任的应用程序从该钥匙串中读取密钥时
SecKeychainUnlock(someKeychain, (UInt32)strlen(keychainPass), keychainPass, TRUE);
UInt32 passwordLen = 0;
void *passData = nil;
const char *cUser_name = [NSUserName() cStringUsingEncoding:NSUTF8StringEncoding];
OSStatus genericPassErr = SecKeychainFindGenericPassword(someKeychain, 0, NULL, strlen(cUser_name), cUser_name, &passwordLen, &passData, NULL);
genericPassErr
等于-25293
,这意味着
Error: 0xFFFF9D33 -25293 The user name or passphrase you entered is not correct.
在代码的早期,我运行SecKeychainSetUserInteractionAllowed(0)
,如果我对此行发表评论,系统会提示我允许应用程序访问钥匙串,如果我授予它,一切都运行良好。但是,重点是我需要能够在不提示用户的情况下这样做。我希望它能像这样工作,因为我将应用程序添加到了ACL中。你知道我做错了什么吗?
当我在附带的屏幕截图中勾选“所有程序都可以访问此项目”单选框时,所有内容都可以正常工作。但我不希望每个人都能访问它,只是列出的应用程序。
答案 0 :(得分:3)
我能够制作类似的测试程序。但是,每次重建工具后,我都必须删除并重新添加工具到始终允许的列表。我没有这样做时得到了相同的错误代码。
以下是代码:
#import <Foundation/Foundation.h>
#import <Security/Security.h>
int main()
{
@autoreleasepool
{
SecKeychainRef kc;
OSStatus status = SecKeychainSetUserInteractionAllowed(false);
printf("status: %d\n", status);
status = SecKeychainOpen("/Users/tsnorri/Library/Keychains/test.keychain", &kc);
printf("status: %d\n", status);
{
char const *keychainPass = "test123";
status = SecKeychainUnlock(kc, (UInt32) strlen(keychainPass), keychainPass, true);
CFStringRef err = SecCopyErrorMessageString(status, NULL);
printf("status: %d err: %s\n", status, [(id) err UTF8String]);
CFRelease(err);
}
UInt32 passwordLen = 0;
void *passData = NULL;
char const *userName = "tsnorri";
char const *serviceName = "test";
{
SecKeychainItemRef item = NULL;
status = SecKeychainFindGenericPassword(kc, strlen(serviceName), serviceName, strlen(userName), userName, &passwordLen, &passData, &item);
CFStringRef err = SecCopyErrorMessageString(status, NULL);
printf("status: %d err: %s\n", status, [(id) err UTF8String]);
CFRelease(err);
}
printf("pass: %s\n", passData);
}
return 0;
}