objective-c - iOS 钥匙串(keychain)问题。作为 SecItemCopyMatching() 的结果,SecKeyRef 始终为 null

标签 objective-c ios keychain

SecKeyRef 始终为 null,即使我没有从任何状态中收到任何错误。我最初认为这是一个电弧问题,但类型转换看起来还不错。任何帮助将不胜感激。

+ (SecKeyRef)addPublicKey:(NSString *)key withTag:(NSString *)tag
    {
        // This will be base64 encoded, decode it.
        NSData *d_key = [key dataUsingEncoding:NSUTF8StringEncoding];

        if (d_key == nil) return (FALSE);

        NSData *d_tag = [NSData dataWithBytes:[tag UTF8String] length:[tag length]];

        // Delete any old lingering key with the same tag
        NSMutableDictionary *publicKey = [[NSMutableDictionary alloc] init];
        [publicKey setObject:(__bridge id) kSecClassKey forKey:(__bridge id)kSecClass];
        [publicKey setObject:(__bridge id) kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
        [publicKey setObject:d_tag forKey:(__bridge id)kSecAttrApplicationTag];
        SecItemDelete((__bridge CFDictionaryRef)publicKey);

        CFTypeRef persistKey = nil;

        // Add persistent version of the key to system keychain
        [publicKey setObject:d_key forKey:(__bridge id)kSecValueData];
        [publicKey setObject:(__bridge id) kSecAttrKeyClassPublic forKey:(__bridge id)kSecAttrKeyClass];
        [publicKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnPersistentRef];

        OSStatus secStatus = SecItemAdd((__bridge CFDictionaryRef)publicKey, &persistKey);

        NSLog(@"OSStatus = %ld", secStatus);  // Always returns no error = 0

        if (persistKey != nil) CFRelease(persistKey);

        if ((secStatus != noErr) && (secStatus != errSecDuplicateItem)) {
            return nil;
        }

        // Now fetch the SecKeyRef version of the key
        SecKeyRef keyRef;

        [publicKey removeObjectForKey:(__bridge id)kSecValueData];
        [publicKey removeObjectForKey:(__bridge id)kSecReturnPersistentRef];
        [publicKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnRef];
        [publicKey setObject:(__bridge id)kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];


        secStatus = SecItemCopyMatching((__bridge CFDictionaryRef)publicKey, (CFTypeRef *)&keyRef);

        NSLog(@"secStatus = %ld", secStatus); // Always returns no error = 0

        return keyRef; // Always null!
    }

最佳答案

我当时正在做类似的事情,偶然发现了这篇文章。我试用了您的代码,它对我来说效果很好,所以我认为它是正确的。我怀疑关键数据有误。我尝试通过这种方法提供错误的关键数据,它给了我一个空引用,就像你说的那样。我正在使用这个从模数和指数构建公钥 (ASN.1 DER)-

https://github.com/meinside/iphonelib/blob/master/security/CryptoUtil.m#L67

请注意有几个待处理的拉取请求。

我认为也许您应该尝试使用 .cer 文件或使用 openssl 生成 rsa key 并使用 CryptoUtil 的模数和指数。

关于objective-c - iOS 钥匙串(keychain)问题。作为 SecItemCopyMatching() 的结果,SecKeyRef 始终为 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11301158/

相关文章:

iphone - UIControl - 更改分配的选择器 : addTarget & removeTarget

ios - 如何在 Swift 中调整 UIImageView 的大小

ios - 计算给定字符串的标签的适当大小

ios - MKMapKit 可拖动注释和绘制多边形

ios - iOS 钥匙串(keychain)中的项目会在应用程序卸载并重新安装后继续存在吗?

ios - 如何将 .cer 文件转换为 .pem 文件

objective-c - 比较 NSCFString 和 NSCFBoolean

iphone - iOS 中涉及屏幕抓取的 Objective-C 和 Cocoa Touch 问题

IOS/objective-C/ Storyboard : Prevent ViewController From Launching Modally

objective-c - Objective-C : Exporting Private and Public Key from Keychain