【问题标题】:Accessing OS X keychain item from trusted application从受信任的应用程序访问 OS X 钥匙串项目
【发布时间】:2014-08-12 07:25:45
【问题描述】:

我正在创建一个钥匙串,然后我正在向其中添加一个带有预定义的受信任应用程序列表的项目:

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。你知道我做错了什么吗?

当我在随附的屏幕截图中勾选“所有程序都可以访问此项目”单选框时,一切都无需提示即可正常工作。但我不希望每个人都能访问它,只是列出的应用程序。

【问题讨论】:

  • SecKeychainUnlock 返回什么?
  • @TuukkaNorri 返回OSStatus的值为0,看来运行正常。
  • 1.) 您是否在将受信任的应用程序添加到 ACL 和尝试访问创建的项目之间重新编译它? // 2.) 你在使用代码签名吗?
  • @mvanallen 1) 我不是 - 我正在编译将自身添加到 ACL 的应用程序,然后尝试从钥匙串中读取,但所有这些都在其单次运行中。 2)不,我不是,如果可能的话,我想保持这种状态。但是,问题可能是我在创建钥匙串并将 ACL 写入其中之后将其移动到不同的位置。我将尝试在目标位置创建它而不是移动它,但我需要为此拥有超级用户权限(我需要写信给/Library)。在您看来,以 root 身份运行 SecKeychainCreate 的最佳方式是什么?

标签: objective-c cocoa keychain security-framework sfauthorizationpluginview


【解决方案1】:

我能够使类似的测试程序工作。但是,每次重建后,我都必须删除该工具并将其重新添加到始终允许的列表中。不这样做时,我确实得到了相同的错误代码。

代码如下:

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

【讨论】:

  • 看起来问题是我在创建钥匙串文件后将其移动到不同的位置,但您的回答为我指明了正确的方向。谢谢,这是你的 50pt :)
猜你喜欢
  • 1970-01-01
  • 2014-08-25
  • 1970-01-01
  • 2020-03-16
  • 2015-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多