【问题标题】:SecItemCopyMatching - Finding specific kSecClassIdentity by nameSecItemCopyMatching - 按名称查找特定的 kSecClassIdentity
【发布时间】:2018-10-06 16:30:32
【问题描述】:

我正在尝试根据其名称 (kSecAttrLabel) 在我的 Mac OS X keychain 中查找特定条目,但看起来 SecItemCopyMatching 已损坏并且在查找以下类型的项目时不应用任何过滤:@ 987654324@.

这段代码将返回 allall 钥匙串中找到的身份,尽管有 kSecAttrLabel: @"MyIdentity" 参数:

NSDictionary *query = @{ (__bridge id)kSecClass: (__bridge NSString*)kSecClassIdentity,
                     (__bridge id)kSecAttrLabel: @"MyIdentity",
                     (__bridge id)kSecMatchLimit: (__bridge id)kSecMatchLimitAll,
                     (__bridge id)kSecReturnAttributes: @YES,
                     (__bridge id)kSecReturnRef: @YES };

OSStatus status;
status = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&privateKey);

当然,我可以通过手动过滤返回的数组来找到我正在寻找的一个身份,但是,除了 IMHO 应该可以正常工作之外,我还想从我的使用SecItemDelete() 的钥匙串,它以查询为参数,就像SecItemCopyMatching。 如果过滤不适用于SecItemCopyMatching,那么它很可能不适用于SecItemDelete,这意味着如果我尝试使用此查询调用SecItemDelete,我将简单地删除我的钥匙串的内容。

我做错了什么?

【问题讨论】:

    标签: macos keychain


    【解决方案1】:

    我想我刚刚找到了解决方案。有人在on another forum 上建议

    在身份上使用标签很棘手,因为身份不是作为原子项目存储在钥匙串中,而是作为单独的私钥和证书存储,并且这些项目以不同的方式使用标签。

    这让我意识到一个解决方案是使用SecItemCopyMatching 按标签搜索证书,然后使用SecIdentityCreateWithCertificate 创建身份。后一个调用应该在钥匙串中找到匹配的私钥。这是在 macOS Mojave 上似乎对我有用的完整代码(C++ 中):

    SecIdentityRef identity = nullptr;
    const char* certificateName = ...;
    const void* keys[] = {
        kSecClass,
        kSecMatchLimit,
        kSecReturnRef,
        kSecAttrLabel
    };
    const void* values[] = {
        kSecClassCertificate,
        kSecMatchLimitOne,
        kCFBooleanTrue,
        CFStringCreateWithCString(nullptr, certificateName, kCFStringEncodingUTF8)
    };
    CFDictionaryRef query = CFDictionaryCreate(nullptr, keys, values, 4, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
    CFTypeRef result;
    OSStatus status = SecItemCopyMatching(query, &result);
    CFRelease(query);
    CFRelease(values[3]);
    if (status) {
        // error
    }
    else {
        SecCertificateRef certificate = (SecCertificateRef)result;
        status = SecIdentityCreateWithCertificate(nullptr, certificate, &identity);
        CFRelease(certificate);
        if (status) {
            // error
        }
    }
    

    【讨论】:

      【解决方案2】:

      我遇到了类似的问题,但我使用的是 kSecAttrApplicationTag 而不是 kSecAttrLabel。无论如何,我不是客观的 c 也不是 IOS 安全专家。事实证明我用来创建查找标签的方法不正确。这对我有用:

      - (void) getOrCreateKey: (NSNumber*)bits publicIdentifier:(NSString*)publicID
      
      // no!  This appears in several samples, but did not work for me on iOS
      // NSData * publicLookupTag = [NSData dataWithBytes:publicId length:strlen((const char *)publicId)];
      //
      // yes!
      NSData * publicLookupTag = [NSData dataWithBytes:[publicId UTF8String] length:publicId.length];
      
      NSMutableDictionary *queryPublicKey = [[NSMutableDictionary alloc] init];
      
      [queryPublicKey setObject:(id)kSecClassKey                forKey:(id)kSecClass];
      [queryPublicKey setObject:publicLookupTag                 forKey:(id)kSecAttrApplicationTag];
      [queryPublicKey setObject:(id)kSecAttrKeyTypeRSA          forKey:(id)kSecAttrKeyType];
      [queryPublicKey setObject:[NSNumber numberWithBool:YES]   forKey:(id)kSecReturnRef];
      
      OSStatus lookupStatus = noErr;
      lookupStatus = SecItemCopyMatching((CFDictionaryRef)queryPublicKey, (CFTypeRef *)&publicLookupKey);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-05-05
        • 2016-05-22
        • 2022-01-23
        • 2020-10-31
        • 1970-01-01
        • 2015-04-29
        相关资源
        最近更新 更多